diff --git a/.gitignore b/.gitignore index fb7d69711..319f85b7f 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,8 @@ _ReSharper*/ .vs/ /ILSpy.AddIn/Packages/* /ILSpy.AddIn/source.extension.vsixmanifest +/ICSharpCode.Decompiler.Tests/TestCases/Disassembler/Pretty/*.dll +/ICSharpCode.Decompiler.Tests/TestCases/Disassembler/Pretty/*.result.il /ICSharpCode.Decompiler.Tests/TestCases/Correctness/*.exe /ICSharpCode.Decompiler.Tests/TestCases/Correctness/*.exe.config /ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec diff --git a/ICSharpCode.Decompiler.PdbProvider.Cecil/ICSharpCode.Decompiler.PdbProvider.Cecil.csproj b/ICSharpCode.Decompiler.PdbProvider.Cecil/ICSharpCode.Decompiler.PdbProvider.Cecil.csproj index c545c43a9..0b0a2724e 100644 --- a/ICSharpCode.Decompiler.PdbProvider.Cecil/ICSharpCode.Decompiler.PdbProvider.Cecil.csproj +++ b/ICSharpCode.Decompiler.PdbProvider.Cecil/ICSharpCode.Decompiler.PdbProvider.Cecil.csproj @@ -7,7 +7,7 @@ - + diff --git a/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs b/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs index ad3399bf9..58edfd007 100644 --- a/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs @@ -46,152 +46,158 @@ namespace ICSharpCode.Decompiler.Tests } } - static readonly CSharpCompilerOptions[] noMonoOptions = + static readonly CompilerOptions[] noMonoOptions = { - CSharpCompilerOptions.None, - CSharpCompilerOptions.Optimize, - CSharpCompilerOptions.UseRoslyn, - CSharpCompilerOptions.Optimize | CSharpCompilerOptions.UseRoslyn, + CompilerOptions.None, + CompilerOptions.Optimize, + CompilerOptions.UseRoslyn, + CompilerOptions.Optimize | CompilerOptions.UseRoslyn, }; - static readonly CSharpCompilerOptions[] defaultOptions = + static readonly CompilerOptions[] defaultOptions = { - CSharpCompilerOptions.None, - CSharpCompilerOptions.Optimize, - CSharpCompilerOptions.UseRoslyn, - CSharpCompilerOptions.Optimize | CSharpCompilerOptions.UseRoslyn, - CSharpCompilerOptions.UseMcs, - CSharpCompilerOptions.Optimize | CSharpCompilerOptions.UseMcs + CompilerOptions.None, + CompilerOptions.Optimize, + CompilerOptions.UseRoslyn, + CompilerOptions.Optimize | CompilerOptions.UseRoslyn, + CompilerOptions.UseMcs, + CompilerOptions.Optimize | CompilerOptions.UseMcs }; - static readonly CSharpCompilerOptions[] roslynOnlyOptions = + static readonly CompilerOptions[] roslynOnlyOptions = { - CSharpCompilerOptions.UseRoslyn, - CSharpCompilerOptions.Optimize | CSharpCompilerOptions.UseRoslyn + CompilerOptions.UseRoslyn, + CompilerOptions.Optimize | CompilerOptions.UseRoslyn }; [Test] - public void Comparisons([ValueSource("defaultOptions")] CSharpCompilerOptions options) + public void Comparisons([ValueSource("defaultOptions")] CompilerOptions options) { RunCS(options: options); } [Test] - public void Conversions([ValueSource("defaultOptions")] CSharpCompilerOptions options) + public void Conversions([ValueSource("defaultOptions")] CompilerOptions options) { RunCS(options: options); } [Test] - public void FloatingPointArithmetic([ValueSource("defaultOptions")] CSharpCompilerOptions options) + public void FloatingPointArithmetic([ValueSource("defaultOptions")] CompilerOptions options) { RunCS(options: options); } [Test] - public void HelloWorld([ValueSource("defaultOptions")] CSharpCompilerOptions options) + public void HelloWorld([ValueSource("defaultOptions")] CompilerOptions options) { RunCS(options: options); } [Test] - public void ControlFlow([ValueSource("defaultOptions")] CSharpCompilerOptions options) + public void ControlFlow([ValueSource("defaultOptions")] CompilerOptions options) { RunCS(options: options); } [Test] - public void CompoundAssignment([ValueSource("defaultOptions")] CSharpCompilerOptions options) + public void CompoundAssignment([ValueSource("defaultOptions")] CompilerOptions options) { RunCS(options: options); } [Test] - public void PropertiesAndEvents([ValueSource("defaultOptions")] CSharpCompilerOptions options) + public void PropertiesAndEvents([ValueSource("defaultOptions")] CompilerOptions options) { RunCS(options: options); } [Test] - public void Switch([ValueSource("defaultOptions")] CSharpCompilerOptions options) + public void Switch([ValueSource("defaultOptions")] CompilerOptions options) { RunCS(options: options); } [Test] - public void Using([ValueSource("defaultOptions")] CSharpCompilerOptions options) + public void Using([ValueSource("defaultOptions")] CompilerOptions options) { RunCS(options: options); } [Test] - public void Loops([ValueSource("defaultOptions")] CSharpCompilerOptions options) + public void Loops([ValueSource("defaultOptions")] CompilerOptions options) { RunCS(options: options); } [Test] - public void NullableTests([ValueSource("defaultOptions")] CSharpCompilerOptions options) + public void NullableTests([ValueSource("defaultOptions")] CompilerOptions options) { RunCS(options: options); } [Test] - public void Generics([ValueSource("defaultOptions")] CSharpCompilerOptions options) + public void Generics([ValueSource("defaultOptions")] CompilerOptions options) { RunCS(options: options); } [Test] - public void ValueTypeCall([ValueSource("defaultOptions")] CSharpCompilerOptions options) + public void ValueTypeCall([ValueSource("defaultOptions")] CompilerOptions options) { RunCS(options: options); } [Test] - public void InitializerTests([ValueSource("defaultOptions")] CSharpCompilerOptions options) + public void InitializerTests([ValueSource("defaultOptions")] CompilerOptions options) { RunCS(options: options); } [Test] - public void DecimalFields([ValueSource("defaultOptions")] CSharpCompilerOptions options) + public void DecimalFields([ValueSource("defaultOptions")] CompilerOptions options) { RunCS(options: options); } [Test] - public void UndocumentedExpressions([ValueSource("noMonoOptions")] CSharpCompilerOptions options) + public void UndocumentedExpressions([ValueSource("noMonoOptions")] CompilerOptions options) { RunCS(options: options); } [Test] - public void MemberLookup([ValueSource("defaultOptions")] CSharpCompilerOptions options) + public void Uninit([ValueSource("noMonoOptions")] CompilerOptions options) + { + RunVB(options: options); + } + + [Test] + public void MemberLookup([ValueSource("defaultOptions")] CompilerOptions options) { RunCS(options: options); } [Test] - public void OverloadResolution([ValueSource("defaultOptions")] CSharpCompilerOptions options) + public void OverloadResolution([ValueSource("defaultOptions")] CompilerOptions options) { RunCS(options: options); } [Test] - public void ExpressionTrees([ValueSource("defaultOptions")] CSharpCompilerOptions options) + public void ExpressionTrees([ValueSource("defaultOptions")] CompilerOptions options) { RunCS(options: options); } [Test] - public void NullPropagation([ValueSource("roslynOnlyOptions")] CSharpCompilerOptions options) + public void NullPropagation([ValueSource("roslynOnlyOptions")] CompilerOptions options) { RunCS(options: options); } [Test] - public void RefLocalsAndReturns([ValueSource("roslynOnlyOptions")] CSharpCompilerOptions options) + public void RefLocalsAndReturns([ValueSource("roslynOnlyOptions")] CompilerOptions options) { RunCS(options: options); } @@ -199,10 +205,10 @@ namespace ICSharpCode.Decompiler.Tests [Test] public void BitNot([Values(false, true)] bool force32Bit) { - CSharpCompilerOptions compiler = CSharpCompilerOptions.UseDebug; + CompilerOptions compiler = CompilerOptions.UseDebug; AssemblerOptions asm = AssemblerOptions.None; if (force32Bit) { - compiler |= CSharpCompilerOptions.Force32Bit; + compiler |= CompilerOptions.Force32Bit; asm |= AssemblerOptions.Force32Bit; } RunIL("BitNot.il", compiler, asm); @@ -217,79 +223,79 @@ namespace ICSharpCode.Decompiler.Tests [Test] public void StackTypes([Values(false, true)] bool force32Bit) { - CSharpCompilerOptions compiler = CSharpCompilerOptions.UseRoslyn | CSharpCompilerOptions.UseDebug; + CompilerOptions compiler = CompilerOptions.UseRoslyn | CompilerOptions.UseDebug; AssemblerOptions asm = AssemblerOptions.None; if (force32Bit) { - compiler |= CSharpCompilerOptions.Force32Bit; + compiler |= CompilerOptions.Force32Bit; asm |= AssemblerOptions.Force32Bit; } RunIL("StackTypes.il", compiler, asm); } [Test] - public void UnsafeCode([ValueSource("defaultOptions")] CSharpCompilerOptions options) + public void UnsafeCode([ValueSource("defaultOptions")] CompilerOptions options) { - if (options.HasFlag(CSharpCompilerOptions.UseMcs)) { + if (options.HasFlag(CompilerOptions.UseMcs)) { Assert.Ignore("Decompiler bug with mono!"); } RunCS(options: options); } [Test] - public void ConditionalAttr([ValueSource("defaultOptions")] CSharpCompilerOptions options) + public void ConditionalAttr([ValueSource("defaultOptions")] CompilerOptions options) { RunCS(options: options); } [Test] - public void TrickyTypes([ValueSource("defaultOptions")] CSharpCompilerOptions options) + public void TrickyTypes([ValueSource("defaultOptions")] CompilerOptions options) { RunCS(options: options); } [Test] - public void Capturing([ValueSource("defaultOptions")] CSharpCompilerOptions options) + public void Capturing([ValueSource("defaultOptions")] CompilerOptions options) { RunCS(options: options); } [Test] - public void YieldReturn([ValueSource("defaultOptions")] CSharpCompilerOptions options) + public void YieldReturn([ValueSource("defaultOptions")] CompilerOptions options) { - if (options.HasFlag(CSharpCompilerOptions.UseMcs)) { + if (options.HasFlag(CompilerOptions.UseMcs)) { Assert.Ignore("Decompiler bug with mono!"); } RunCS(options: options); } [Test] - public void Async([ValueSource("noMonoOptions")] CSharpCompilerOptions options) + public void Async([ValueSource("noMonoOptions")] CompilerOptions options) { RunCS(options: options); } [Test] - public void LINQRaytracer([ValueSource("defaultOptions")] CSharpCompilerOptions options) + public void LINQRaytracer([ValueSource("defaultOptions")] CompilerOptions options) { RunCS(options: options); } [Test] - public void MiniJSON([ValueSource("defaultOptions")] CSharpCompilerOptions options) + public void MiniJSON([ValueSource("defaultOptions")] CompilerOptions options) { - if (options.HasFlag(CSharpCompilerOptions.UseMcs)) { + if (options.HasFlag(CompilerOptions.UseMcs)) { Assert.Ignore("Decompiler bug with mono!"); } RunCS(options: options); } [Test] - public void LocalFunctions([ValueSource(nameof(roslynOnlyOptions))] CSharpCompilerOptions options) + public void LocalFunctions([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions options) { RunCS(options: options); } - void RunCS([CallerMemberName] string testName = null, CSharpCompilerOptions options = CSharpCompilerOptions.UseDebug) + void RunCS([CallerMemberName] string testName = null, CompilerOptions options = CompilerOptions.UseDebug) { string testFileName = testName + ".cs"; string testOutputFileName = testName + Tester.GetSuffix(options) + ".exe"; @@ -299,12 +305,12 @@ namespace ICSharpCode.Decompiler.Tests outputFile = Tester.CompileCSharp(Path.Combine(TestCasePath, testFileName), options, outputFileName: Path.Combine(TestCasePath, testOutputFileName)); string decompiledCodeFile = Tester.DecompileCSharp(outputFile.PathToAssembly, Tester.GetSettings(options)); - if (options.HasFlag(CSharpCompilerOptions.UseMcs)) { + if (options.HasFlag(CompilerOptions.UseMcs)) { // For second pass, use roslyn instead of mcs. // 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 &= ~CSharpCompilerOptions.UseMcs; - options |= CSharpCompilerOptions.UseRoslyn; + options &= ~CompilerOptions.UseMcs; + options |= CompilerOptions.UseRoslyn; // Also, add an .exe.config so that we consistently use the .NET 4.x runtime. File.WriteAllText(outputFile.PathToAssembly + ".config", @" @@ -327,7 +333,31 @@ namespace ICSharpCode.Decompiler.Tests } } - void RunIL(string testFileName, CSharpCompilerOptions options = CSharpCompilerOptions.UseDebug, AssemblerOptions asmOptions = AssemblerOptions.None) + void RunVB([CallerMemberName] string testName = null, CompilerOptions options = CompilerOptions.UseDebug) + { + string testFileName = testName + ".vb"; + string testOutputFileName = testName + Tester.GetSuffix(options) + ".exe"; + CompilerResults outputFile = null, decompiledOutputFile = null; + + try { + outputFile = Tester.CompileVB(Path.Combine(TestCasePath, testFileName), options, + outputFileName: Path.Combine(TestCasePath, testOutputFileName)); + string decompiledCodeFile = Tester.DecompileCSharp(outputFile.PathToAssembly, Tester.GetSettings(options)); + decompiledOutputFile = Tester.CompileCSharp(decompiledCodeFile, options); + + Tester.RunAndCompareOutput(testFileName, outputFile.PathToAssembly, decompiledOutputFile.PathToAssembly, decompiledCodeFile); + + File.Delete(decompiledCodeFile); + File.Delete(decompiledOutputFile.PathToAssembly); + } finally { + if (outputFile != null) + outputFile.TempFiles.Delete(); + if (decompiledOutputFile != null) + decompiledOutputFile.TempFiles.Delete(); + } + } + + void RunIL(string testFileName, CompilerOptions options = CompilerOptions.UseDebug, AssemblerOptions asmOptions = AssemblerOptions.None) { string outputFile = null; CompilerResults decompiledOutputFile = null; diff --git a/ICSharpCode.Decompiler.Tests/Helpers/Tester.VB.cs b/ICSharpCode.Decompiler.Tests/Helpers/Tester.VB.cs index 8b766f17b..b543842f8 100644 --- a/ICSharpCode.Decompiler.Tests/Helpers/Tester.VB.cs +++ b/ICSharpCode.Decompiler.Tests/Helpers/Tester.VB.cs @@ -12,71 +12,26 @@ using Microsoft.VisualBasic; namespace ICSharpCode.Decompiler.Tests.Helpers { - [Flags] - public enum VBCompilerOptions - { - None, - Optimize = 0x1, - UseDebug = 0x2, - Force32Bit = 0x4, - Library = 0x8, - UseRoslyn = 0x10, - } - partial class Tester { - internal static string GetSuffix(VBCompilerOptions vbcOptions) - { - string suffix = ""; - if ((vbcOptions & VBCompilerOptions.Optimize) != 0) - suffix += ".opt"; - if ((vbcOptions & VBCompilerOptions.Force32Bit) != 0) - suffix += ".32"; - if ((vbcOptions & VBCompilerOptions.UseDebug) != 0) - suffix += ".dbg"; - if ((vbcOptions & VBCompilerOptions.UseRoslyn) != 0) - suffix += ".roslyn"; - return suffix; - } - - public static List> GetPreprocessorSymbols(VBCompilerOptions flags) - { - var preprocessorSymbols = new List>(); - if (flags.HasFlag(VBCompilerOptions.UseDebug)) { - preprocessorSymbols.Add(new KeyValuePair("DEBUG", 1)); - } - if (flags.HasFlag(VBCompilerOptions.Optimize)) { - preprocessorSymbols.Add(new KeyValuePair("OPT", 1)); - } - if (flags.HasFlag(VBCompilerOptions.UseRoslyn)) { - preprocessorSymbols.Add(new KeyValuePair("ROSLYN", 1)); - preprocessorSymbols.Add(new KeyValuePair("VB11", 1)); - preprocessorSymbols.Add(new KeyValuePair("VB14", 1)); - preprocessorSymbols.Add(new KeyValuePair("VB15", 1)); - } else { - preprocessorSymbols.Add(new KeyValuePair("LEGACY_VBC", 1)); - } - return preprocessorSymbols; - } - - public static CompilerResults CompileVB(string sourceFileName, VBCompilerOptions flags = VBCompilerOptions.UseDebug, string outputFileName = null) + public static CompilerResults CompileVB(string sourceFileName, CompilerOptions flags = CompilerOptions.UseDebug, string outputFileName = null) { List sourceFileNames = new List { sourceFileName }; foreach (Match match in Regex.Matches(File.ReadAllText(sourceFileName), @"#include ""([\w\d./]+)""")) { sourceFileNames.Add(Path.GetFullPath(Path.Combine(Path.GetDirectoryName(sourceFileName), match.Groups[1].Value))); } - var preprocessorSymbols = GetPreprocessorSymbols(flags); + var preprocessorSymbols = GetPreprocessorSymbols(flags).Select(symbol => new KeyValuePair(symbol, 1)).ToList(); - if (flags.HasFlag(VBCompilerOptions.UseRoslyn)) { + if (flags.HasFlag(CompilerOptions.UseRoslyn)) { var parseOptions = new VisualBasicParseOptions(preprocessorSymbols: preprocessorSymbols, languageVersion: LanguageVersion.Latest); var syntaxTrees = sourceFileNames.Select(f => SyntaxFactory.ParseSyntaxTree(File.ReadAllText(f), parseOptions, path: f)); var compilation = VisualBasicCompilation.Create(Path.GetFileNameWithoutExtension(sourceFileName), syntaxTrees, defaultReferences.Value, new VisualBasicCompilationOptions( - flags.HasFlag(VBCompilerOptions.Library) ? OutputKind.DynamicallyLinkedLibrary : OutputKind.ConsoleApplication, - platform: flags.HasFlag(VBCompilerOptions.Force32Bit) ? Platform.X86 : Platform.AnyCpu, - optimizationLevel: flags.HasFlag(VBCompilerOptions.Optimize) ? OptimizationLevel.Release : OptimizationLevel.Debug, + 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()); @@ -90,15 +45,18 @@ namespace ICSharpCode.Decompiler.Tests.Helpers 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 { { "CompilerVersion", "v10.0" } }); + var provider = new VBCodeProvider(new Dictionary { { "CompilerVersion", "v4.0" } }); CompilerParameters options = new CompilerParameters(); - options.GenerateExecutable = !flags.HasFlag(VBCompilerOptions.Library); - options.CompilerOptions = "/o" + (flags.HasFlag(VBCompilerOptions.Optimize) ? "+" : "-"); - options.CompilerOptions += (flags.HasFlag(VBCompilerOptions.UseDebug) ? " /debug" : ""); - options.CompilerOptions += (flags.HasFlag(VBCompilerOptions.Force32Bit) ? " /platform:anycpu32bitpreferred" : ""); + options.GenerateExecutable = !flags.HasFlag(CompilerOptions.Library); + options.CompilerOptions = "/o" + (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) { - options.CompilerOptions += " /d:" + string.Join(";", preprocessorSymbols); + options.CompilerOptions += " /d:" + string.Join(",", preprocessorSymbols.Select(p => $"{p.Key}={p.Value}")); } if (outputFileName != null) { options.OutputAssembly = outputFileName; @@ -107,6 +65,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers options.ReferencedAssemblies.Add("System.dll"); options.ReferencedAssemblies.Add("System.Core.dll"); options.ReferencedAssemblies.Add("System.Xml.dll"); + options.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll"); CompilerResults results = provider.CompileAssemblyFromFile(options, sourceFileNames.ToArray()); if (results.Errors.Cast().Any(e => !e.IsWarning)) { StringBuilder b = new StringBuilder("Compiler error:"); @@ -118,6 +77,5 @@ namespace ICSharpCode.Decompiler.Tests.Helpers return results; } } - } } diff --git a/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs b/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs index 399e399ae..ace9d1ef9 100644 --- a/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs +++ b/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs @@ -42,7 +42,7 @@ using NUnit.Framework; namespace ICSharpCode.Decompiler.Tests.Helpers { [Flags] - public enum CSharpCompilerOptions + public enum CompilerOptions { None, Optimize = 0x1, @@ -189,36 +189,41 @@ namespace ICSharpCode.Decompiler.Tests.Helpers 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(Path.Combine(refAsmPath, "Microsoft.VisualBasic.dll")), MetadataReference.CreateFromFile(typeof(ValueTuple).Assembly.Location), MetadataReference.CreateFromFile(typeof(Span<>).Assembly.Location), }; }); - - public static List GetPreprocessorSymbols(CSharpCompilerOptions flags) + public static List GetPreprocessorSymbols(CompilerOptions flags) { var preprocessorSymbols = new List(); - if (flags.HasFlag(CSharpCompilerOptions.UseDebug)) { + if (flags.HasFlag(CompilerOptions.UseDebug)) { preprocessorSymbols.Add("DEBUG"); } - if (flags.HasFlag(CSharpCompilerOptions.Optimize)) { + if (flags.HasFlag(CompilerOptions.Optimize)) { preprocessorSymbols.Add("OPT"); } - if (flags.HasFlag(CSharpCompilerOptions.UseRoslyn)) { + if (flags.HasFlag(CompilerOptions.UseRoslyn)) { preprocessorSymbols.Add("ROSLYN"); preprocessorSymbols.Add("CS60"); preprocessorSymbols.Add("CS70"); preprocessorSymbols.Add("CS71"); preprocessorSymbols.Add("CS72"); - } else if (flags.HasFlag(CSharpCompilerOptions.UseMcs)) { + preprocessorSymbols.Add("CS73"); + preprocessorSymbols.Add("VB11"); + preprocessorSymbols.Add("VB14"); + preprocessorSymbols.Add("VB15"); + } else if (flags.HasFlag(CompilerOptions.UseMcs)) { preprocessorSymbols.Add("MCS"); } else { preprocessorSymbols.Add("LEGACY_CSC"); + preprocessorSymbols.Add("LEGACY_VBC"); } return preprocessorSymbols; } - public static CompilerResults CompileCSharp(string sourceFileName, CSharpCompilerOptions flags = CSharpCompilerOptions.UseDebug, string outputFileName = null) + public static CompilerResults CompileCSharp(string sourceFileName, CompilerOptions flags = CompilerOptions.UseDebug, string outputFileName = null) { List sourceFileNames = new List { sourceFileName }; foreach (Match match in Regex.Matches(File.ReadAllText(sourceFileName), @"#include ""([\w\d./]+)""")) { @@ -227,15 +232,15 @@ namespace ICSharpCode.Decompiler.Tests.Helpers var preprocessorSymbols = GetPreprocessorSymbols(flags); - if (flags.HasFlag(CSharpCompilerOptions.UseRoslyn)) { + if (flags.HasFlag(CompilerOptions.UseRoslyn)) { var parseOptions = new CSharpParseOptions(preprocessorSymbols: preprocessorSymbols.ToArray(), languageVersion: Microsoft.CodeAnalysis.CSharp.LanguageVersion.Latest); var syntaxTrees = sourceFileNames.Select(f => SyntaxFactory.ParseSyntaxTree(File.ReadAllText(f), parseOptions, path: f)); var compilation = CSharpCompilation.Create(Path.GetFileNameWithoutExtension(sourceFileName), syntaxTrees, defaultReferences.Value, new CSharpCompilationOptions( - flags.HasFlag(CSharpCompilerOptions.Library) ? OutputKind.DynamicallyLinkedLibrary : OutputKind.ConsoleApplication, - platform: flags.HasFlag(CSharpCompilerOptions.Force32Bit) ? Platform.X86 : Platform.AnyCpu, - optimizationLevel: flags.HasFlag(CSharpCompilerOptions.Optimize) ? OptimizationLevel.Release : OptimizationLevel.Debug, + 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 )); @@ -250,7 +255,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers throw new Exception(b.ToString()); } return results; - } else if (flags.HasFlag(CSharpCompilerOptions.UseMcs)) { + } else if (flags.HasFlag(CompilerOptions.UseMcs)) { CompilerResults results = new CompilerResults(new TempFileCollection()); results.PathToAssembly = outputFileName ?? Path.GetTempFileName(); string testBasePath = RoundtripAssembly.TestDir; @@ -259,19 +264,19 @@ namespace ICSharpCode.Decompiler.Tests.Helpers $"git clone https://github.com/icsharpcode/ILSpy-tests \"{testBasePath}\""); } string mcsPath = Path.Combine(testBasePath, @"mcs\2.6.4\bin\gmcs.bat"); - string otherOptions = " -unsafe -o" + (flags.HasFlag(CSharpCompilerOptions.Optimize) ? "+ " : "- "); + string otherOptions = " -unsafe -o" + (flags.HasFlag(CompilerOptions.Optimize) ? "+ " : "- "); - if (flags.HasFlag(CSharpCompilerOptions.Library)) { + if (flags.HasFlag(CompilerOptions.Library)) { otherOptions += "-t:library "; } else { otherOptions += "-t:exe "; } - if (flags.HasFlag(CSharpCompilerOptions.UseDebug)) { + if (flags.HasFlag(CompilerOptions.UseDebug)) { otherOptions += "-g "; } - if (flags.HasFlag(CSharpCompilerOptions.Force32Bit)) { + if (flags.HasFlag(CompilerOptions.Force32Bit)) { otherOptions += "-platform:x86 "; } else { otherOptions += "-platform:anycpu "; @@ -303,10 +308,10 @@ namespace ICSharpCode.Decompiler.Tests.Helpers } else { var provider = new CSharpCodeProvider(new Dictionary { { "CompilerVersion", "v4.0" } }); CompilerParameters options = new CompilerParameters(); - options.GenerateExecutable = !flags.HasFlag(CSharpCompilerOptions.Library); - options.CompilerOptions = "/unsafe /o" + (flags.HasFlag(CSharpCompilerOptions.Optimize) ? "+" : "-"); - options.CompilerOptions += (flags.HasFlag(CSharpCompilerOptions.UseDebug) ? " /debug" : ""); - options.CompilerOptions += (flags.HasFlag(CSharpCompilerOptions.Force32Bit) ? " /platform:anycpu32bitpreferred" : ""); + options.GenerateExecutable = !flags.HasFlag(CompilerOptions.Library); + options.CompilerOptions = "/unsafe /o" + (flags.HasFlag(CompilerOptions.Optimize) ? "+" : "-"); + options.CompilerOptions += (flags.HasFlag(CompilerOptions.UseDebug) ? " /debug" : ""); + options.CompilerOptions += (flags.HasFlag(CompilerOptions.Force32Bit) ? " /platform:anycpu32bitpreferred" : ""); if (preprocessorSymbols.Count > 0) { options.CompilerOptions += " /d:" + string.Join(";", preprocessorSymbols); } @@ -318,6 +323,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers options.ReferencedAssemblies.Add("System.Core.dll"); options.ReferencedAssemblies.Add("System.Xml.dll"); options.ReferencedAssemblies.Add("Microsoft.CSharp.dll"); + options.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll"); CompilerResults results = provider.CompileAssemblyFromFile(options, sourceFileNames.ToArray()); if (results.Errors.Cast().Any(e => !e.IsWarning)) { StringBuilder b = new StringBuilder("Compiler error:"); @@ -330,9 +336,9 @@ namespace ICSharpCode.Decompiler.Tests.Helpers } } - internal static DecompilerSettings GetSettings(CSharpCompilerOptions cscOptions) + internal static DecompilerSettings GetSettings(CompilerOptions cscOptions) { - if (cscOptions.HasFlag(CSharpCompilerOptions.UseRoslyn)) { + if (cscOptions.HasFlag(CompilerOptions.UseRoslyn)) { return new DecompilerSettings(CSharp.LanguageVersion.Latest); } else { return new DecompilerSettings(CSharp.LanguageVersion.CSharp5); @@ -358,18 +364,18 @@ namespace ICSharpCode.Decompiler.Tests.Helpers return decompiler; } - internal static string GetSuffix(CSharpCompilerOptions cscOptions) + internal static string GetSuffix(CompilerOptions cscOptions) { string suffix = ""; - if ((cscOptions & CSharpCompilerOptions.Optimize) != 0) + if ((cscOptions & CompilerOptions.Optimize) != 0) suffix += ".opt"; - if ((cscOptions & CSharpCompilerOptions.Force32Bit) != 0) + if ((cscOptions & CompilerOptions.Force32Bit) != 0) suffix += ".32"; - if ((cscOptions & CSharpCompilerOptions.UseDebug) != 0) + if ((cscOptions & CompilerOptions.UseDebug) != 0) suffix += ".dbg"; - if ((cscOptions & CSharpCompilerOptions.UseRoslyn) != 0) + if ((cscOptions & CompilerOptions.UseRoslyn) != 0) suffix += ".roslyn"; - if ((cscOptions & CSharpCompilerOptions.UseMcs) != 0) + if ((cscOptions & CompilerOptions.UseMcs) != 0) suffix += ".mcs"; return suffix; } diff --git a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj index ddb15c1d5..a2852c603 100644 --- a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj +++ b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj @@ -2,7 +2,7 @@ - net46 + net462 7.3 True @@ -52,6 +52,7 @@ + diff --git a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs index ed2abf072..269193fc7 100644 --- a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs @@ -47,34 +47,34 @@ namespace ICSharpCode.Decompiler.Tests } } - static readonly CSharpCompilerOptions[] noRoslynOptions = + static readonly CompilerOptions[] noRoslynOptions = { - CSharpCompilerOptions.None, - CSharpCompilerOptions.Optimize + CompilerOptions.None, + CompilerOptions.Optimize }; - static readonly CSharpCompilerOptions[] roslynOnlyOptions = + static readonly CompilerOptions[] roslynOnlyOptions = { - CSharpCompilerOptions.UseRoslyn, - CSharpCompilerOptions.Optimize | CSharpCompilerOptions.UseRoslyn + CompilerOptions.UseRoslyn, + CompilerOptions.Optimize | CompilerOptions.UseRoslyn }; - static readonly CSharpCompilerOptions[] defaultOptions = + static readonly CompilerOptions[] defaultOptions = { - CSharpCompilerOptions.None, - CSharpCompilerOptions.Optimize, - CSharpCompilerOptions.UseRoslyn, - CSharpCompilerOptions.Optimize | CSharpCompilerOptions.UseRoslyn + CompilerOptions.None, + CompilerOptions.Optimize, + CompilerOptions.UseRoslyn, + CompilerOptions.Optimize | CompilerOptions.UseRoslyn }; - static readonly CSharpCompilerOptions[] defaultOptionsWithMcs = + static readonly CompilerOptions[] defaultOptionsWithMcs = { - CSharpCompilerOptions.None, - CSharpCompilerOptions.Optimize, - CSharpCompilerOptions.UseRoslyn, - CSharpCompilerOptions.Optimize | CSharpCompilerOptions.UseRoslyn, - CSharpCompilerOptions.UseMcs, - CSharpCompilerOptions.Optimize | CSharpCompilerOptions.UseMcs + CompilerOptions.None, + CompilerOptions.Optimize, + CompilerOptions.UseRoslyn, + CompilerOptions.Optimize | CompilerOptions.UseRoslyn, + CompilerOptions.UseMcs, + CompilerOptions.Optimize | CompilerOptions.UseMcs }; [Test] @@ -85,316 +85,316 @@ namespace ICSharpCode.Decompiler.Tests } [Test] - public void InlineAssignmentTest([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void InlineAssignmentTest([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void CompoundAssignmentTest([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void CompoundAssignmentTest([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void ShortCircuit([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void ShortCircuit([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void CustomShortCircuitOperators([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void CustomShortCircuitOperators([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void ExceptionHandling([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void ExceptionHandling([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings { NullPropagation = false, // legacy csc generates a dead store in debug builds - RemoveDeadCode = (cscOptions == CSharpCompilerOptions.None) + RemoveDeadCode = (cscOptions == CompilerOptions.None) }); } [Test] - public void Switch([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void Switch([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings { // legacy csc generates a dead store in debug builds - RemoveDeadCode = (cscOptions == CSharpCompilerOptions.None) + RemoveDeadCode = (cscOptions == CompilerOptions.None) }); } [Test] - public void ReduceNesting([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void ReduceNesting([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void DelegateConstruction([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void DelegateConstruction([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void AnonymousTypes([ValueSource(nameof(defaultOptionsWithMcs))] CSharpCompilerOptions cscOptions) + public void AnonymousTypes([ValueSource(nameof(defaultOptionsWithMcs))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void Async([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void Async([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void Lock([ValueSource(nameof(defaultOptionsWithMcs))] CSharpCompilerOptions cscOptions) + public void Lock([ValueSource(nameof(defaultOptionsWithMcs))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void Using([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void Using([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void LiftedOperators([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void LiftedOperators([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void Generics([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void Generics([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void Loops([ValueSource(nameof(defaultOptionsWithMcs))] CSharpCompilerOptions cscOptions) + public void Loops([ValueSource(nameof(defaultOptionsWithMcs))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings { // legacy csc generates a dead store in debug builds - RemoveDeadCode = (cscOptions == CSharpCompilerOptions.None) + RemoveDeadCode = (cscOptions == CompilerOptions.None) }); } [Test] - public void PropertiesAndEvents([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void PropertiesAndEvents([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void AutoProperties([ValueSource(nameof(roslynOnlyOptions))] CSharpCompilerOptions cscOptions) + public void AutoProperties([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void QueryExpressions([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void QueryExpressions([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void TypeAnalysisTests([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void TypeAnalysisTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void CheckedUnchecked([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void CheckedUnchecked([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void UnsafeCode([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void UnsafeCode([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void ConstructorInitializers([ValueSource(nameof(defaultOptionsWithMcs))] CSharpCompilerOptions cscOptions) + public void ConstructorInitializers([ValueSource(nameof(defaultOptionsWithMcs))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void PInvoke([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void PInvoke([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { // This tests needs our own disassembler; ildasm has a bug with marshalinfo. RunForLibrary(cscOptions: cscOptions, asmOptions: AssemblerOptions.UseOwnDisassembler); } [Test] - public void InitializerTests([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void InitializerTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void DynamicTests([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void DynamicTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void ExpressionTrees([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void ExpressionTrees([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void FixProxyCalls([Values(CSharpCompilerOptions.None, CSharpCompilerOptions.Optimize, CSharpCompilerOptions.UseRoslyn)] CSharpCompilerOptions cscOptions) + public void FixProxyCalls([Values(CompilerOptions.None, CompilerOptions.Optimize, CompilerOptions.UseRoslyn)] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void VariableNaming([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void VariableNaming([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void VariableNamingWithoutSymbols([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void VariableNamingWithoutSymbols([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings { UseDebugSymbols = false }); } [Test] - public void CS72_PrivateProtected([ValueSource(nameof(roslynOnlyOptions))] CSharpCompilerOptions cscOptions) + public void CS72_PrivateProtected([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void AsyncMain([ValueSource(nameof(roslynOnlyOptions))] CSharpCompilerOptions cscOptions) + public void AsyncMain([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions) { Run(cscOptions: cscOptions); } [Test] - public void NullPropagation([ValueSource(nameof(roslynOnlyOptions))] CSharpCompilerOptions cscOptions) + public void NullPropagation([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void CS6_StringInterpolation([ValueSource(nameof(roslynOnlyOptions))] CSharpCompilerOptions cscOptions) + public void CS6_StringInterpolation([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions) { Run(cscOptions: cscOptions); } [Test] - public void CS73_StackAllocInitializers([ValueSource(nameof(roslynOnlyOptions))] CSharpCompilerOptions cscOptions) + public void CS73_StackAllocInitializers([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void RefLocalsAndReturns([ValueSource(nameof(roslynOnlyOptions))] CSharpCompilerOptions cscOptions) + public void RefLocalsAndReturns([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void WellKnownConstants([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void WellKnownConstants([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void QualifierTests([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void QualifierTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void TupleTests([ValueSource(nameof(roslynOnlyOptions))] CSharpCompilerOptions cscOptions) + public void TupleTests([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void NamedArguments([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void NamedArguments([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void OptionalArguments([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void OptionalArguments([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void ConstantsTests([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void ConstantsTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void Issue1080([ValueSource(nameof(roslynOnlyOptions))] CSharpCompilerOptions cscOptions) + public void Issue1080([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void AssemblyCustomAttributes([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void AssemblyCustomAttributes([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void CustomAttributes([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void CustomAttributes([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void CustomAttributeConflicts([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void CustomAttributeConflicts([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void CustomAttributeSamples([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void CustomAttributeSamples([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void MemberTests([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void MemberTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void TypeTests([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void TypeTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } [Test] - public void YieldReturn([ValueSource(nameof(defaultOptions))] CSharpCompilerOptions cscOptions) + public void YieldReturn([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } - void RunForLibrary([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CSharpCompilerOptions cscOptions = CSharpCompilerOptions.None, DecompilerSettings decompilerSettings = null) + void RunForLibrary([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CompilerOptions cscOptions = CompilerOptions.None, DecompilerSettings decompilerSettings = null) { - Run(testName, asmOptions | AssemblerOptions.Library, cscOptions | CSharpCompilerOptions.Library, decompilerSettings); + Run(testName, asmOptions | AssemblerOptions.Library, cscOptions | CompilerOptions.Library, decompilerSettings); } - void Run([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CSharpCompilerOptions cscOptions = CSharpCompilerOptions.None, DecompilerSettings decompilerSettings = null) + void Run([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CompilerOptions cscOptions = CompilerOptions.None, DecompilerSettings decompilerSettings = null) { var ilFile = Path.Combine(TestCasePath, testName) + Tester.GetSuffix(cscOptions) + ".il"; var csFile = Path.Combine(TestCasePath, testName + ".cs"); @@ -404,7 +404,7 @@ namespace ICSharpCode.Decompiler.Tests CompilerResults output = null; try { string outputFile = Path.ChangeExtension(ilFile, - cscOptions.HasFlag(CSharpCompilerOptions.Library) ? ".dll" : ".exe"); + cscOptions.HasFlag(CompilerOptions.Library) ? ".dll" : ".exe"); output = Tester.CompileCSharp(csFile, cscOptions, outputFile); Tester.Disassemble(output.PathToAssembly, ilFile, asmOptions); } finally { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Correctness/Uninit.vb b/ICSharpCode.Decompiler.Tests/TestCases/Correctness/Uninit.vb new file mode 100644 index 000000000..209c9fa19 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Correctness/Uninit.vb @@ -0,0 +1,21 @@ +Imports System + +Module UninitTest + Sub Main() + Dim i = 0 + Dim result As Integer = -5 + Dim num As Integer + Do + If num > result Then + num += 5 + result += 5 + End If + result += 1 + i += 1 + If i > 10 Then + Exit Do + End If + Loop + Console.WriteLine(result) + End Sub +End Module \ No newline at end of file diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.cs index f3ad3c213..da8f4b369 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.cs @@ -16,6 +16,7 @@ // 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; namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty { @@ -96,5 +97,19 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty { return new T[size1, size2]; } + + public Type[] TestTypeOf() + { + return new Type[8] { + typeof(int), + typeof(int[]), + typeof(GenericClass<>), + typeof(GenericClass), + typeof(GenericClass), + typeof(Dictionary<, >), + typeof(List.Enumerator), + typeof(List<>.Enumerator) + }; + } } } diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.il index 7dedb9a29..09dd68e77 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.il @@ -304,6 +304,65 @@ IL_000c: ret } // end of method Generics::NewArray + .method public hidebysig instance class [mscorlib]System.Type[] + TestTypeOf() cil managed + { + // Code size 118 (0x76) + .maxstack 3 + .locals init (class [mscorlib]System.Type[] V_0, + class [mscorlib]System.Type[] V_1) + IL_0000: nop + IL_0001: ldc.i4.8 + IL_0002: newarr [mscorlib]System.Type + IL_0007: stloc.1 + IL_0008: ldloc.1 + IL_0009: ldc.i4.0 + IL_000a: ldtoken [mscorlib]System.Int32 + IL_000f: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) + IL_0014: stelem.ref + IL_0015: ldloc.1 + IL_0016: ldc.i4.1 + IL_0017: ldtoken int32[] + IL_001c: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) + IL_0021: stelem.ref + IL_0022: ldloc.1 + IL_0023: ldc.i4.2 + IL_0024: ldtoken ICSharpCode.Decompiler.Tests.TestCases.Pretty.Generics/GenericClass`1 + IL_0029: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) + IL_002e: stelem.ref + IL_002f: ldloc.1 + IL_0030: ldc.i4.3 + IL_0031: ldtoken class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Generics/GenericClass`1 + IL_0036: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) + IL_003b: stelem.ref + IL_003c: ldloc.1 + IL_003d: ldc.i4.4 + IL_003e: ldtoken class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Generics/GenericClass`1 + IL_0043: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) + IL_0048: stelem.ref + IL_0049: ldloc.1 + IL_004a: ldc.i4.5 + IL_004b: ldtoken [mscorlib]System.Collections.Generic.Dictionary`2 + IL_0050: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) + IL_0055: stelem.ref + IL_0056: ldloc.1 + IL_0057: ldc.i4.6 + IL_0058: ldtoken valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator + IL_005d: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) + IL_0062: stelem.ref + IL_0063: ldloc.1 + IL_0064: ldc.i4.7 + IL_0065: ldtoken [mscorlib]System.Collections.Generic.List`1/Enumerator + IL_006a: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) + IL_006f: stelem.ref + IL_0070: ldloc.1 + IL_0071: stloc.0 + IL_0072: br.s IL_0074 + + IL_0074: ldloc.0 + IL_0075: ret + } // end of method Generics::TestTypeOf + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.opt.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.opt.il index af5b2d1a4..d8e83a93d 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.opt.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.opt.il @@ -231,6 +231,59 @@ IL_0007: ret } // end of method Generics::NewArray + .method public hidebysig instance class [mscorlib]System.Type[] + TestTypeOf() cil managed + { + // Code size 113 (0x71) + .maxstack 3 + .locals init (class [mscorlib]System.Type[] V_0) + IL_0000: ldc.i4.8 + IL_0001: newarr [mscorlib]System.Type + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: ldc.i4.0 + IL_0009: ldtoken [mscorlib]System.Int32 + IL_000e: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) + IL_0013: stelem.ref + IL_0014: ldloc.0 + IL_0015: ldc.i4.1 + IL_0016: ldtoken int32[] + IL_001b: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) + IL_0020: stelem.ref + IL_0021: ldloc.0 + IL_0022: ldc.i4.2 + IL_0023: ldtoken ICSharpCode.Decompiler.Tests.TestCases.Pretty.Generics/GenericClass`1 + IL_0028: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) + IL_002d: stelem.ref + IL_002e: ldloc.0 + IL_002f: ldc.i4.3 + IL_0030: ldtoken class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Generics/GenericClass`1 + IL_0035: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) + IL_003a: stelem.ref + IL_003b: ldloc.0 + IL_003c: ldc.i4.4 + IL_003d: ldtoken class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Generics/GenericClass`1 + IL_0042: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) + IL_0047: stelem.ref + IL_0048: ldloc.0 + IL_0049: ldc.i4.5 + IL_004a: ldtoken [mscorlib]System.Collections.Generic.Dictionary`2 + IL_004f: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) + IL_0054: stelem.ref + IL_0055: ldloc.0 + IL_0056: ldc.i4.6 + IL_0057: ldtoken valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator + IL_005c: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) + IL_0061: stelem.ref + IL_0062: ldloc.0 + IL_0063: ldc.i4.7 + IL_0064: ldtoken [mscorlib]System.Collections.Generic.List`1/Enumerator + IL_0069: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) + IL_006e: stelem.ref + IL_006f: ldloc.0 + IL_0070: ret + } // end of method Generics::TestTypeOf + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.opt.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.opt.roslyn.il index 3112d5a7a..86ef337db 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.opt.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.opt.roslyn.il @@ -222,6 +222,56 @@ IL_0007: ret } // end of method Generics::NewArray + .method public hidebysig instance class [mscorlib]System.Type[] + TestTypeOf() cil managed + { + // Code size 111 (0x6f) + .maxstack 4 + IL_0000: ldc.i4.8 + IL_0001: newarr [mscorlib]System.Type + IL_0006: dup + IL_0007: ldc.i4.0 + IL_0008: ldtoken [mscorlib]System.Int32 + IL_000d: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) + IL_0012: stelem.ref + IL_0013: dup + IL_0014: ldc.i4.1 + IL_0015: ldtoken int32[] + IL_001a: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) + IL_001f: stelem.ref + IL_0020: dup + IL_0021: ldc.i4.2 + IL_0022: ldtoken ICSharpCode.Decompiler.Tests.TestCases.Pretty.Generics/GenericClass`1 + IL_0027: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) + IL_002c: stelem.ref + IL_002d: dup + IL_002e: ldc.i4.3 + IL_002f: ldtoken class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Generics/GenericClass`1 + IL_0034: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) + IL_0039: stelem.ref + IL_003a: dup + IL_003b: ldc.i4.4 + IL_003c: ldtoken class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Generics/GenericClass`1 + IL_0041: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) + IL_0046: stelem.ref + IL_0047: dup + IL_0048: ldc.i4.5 + IL_0049: ldtoken [mscorlib]System.Collections.Generic.Dictionary`2 + IL_004e: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) + IL_0053: stelem.ref + IL_0054: dup + IL_0055: ldc.i4.6 + IL_0056: ldtoken valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator + IL_005b: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) + IL_0060: stelem.ref + IL_0061: dup + IL_0062: ldc.i4.7 + IL_0063: ldtoken [mscorlib]System.Collections.Generic.List`1/Enumerator + IL_0068: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) + IL_006d: stelem.ref + IL_006e: ret + } // end of method Generics::TestTypeOf + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.roslyn.il index a433f6f70..fb056af8f 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.roslyn.il @@ -298,6 +298,62 @@ IL_000c: ret } // end of method Generics::NewArray + .method public hidebysig instance class [mscorlib]System.Type[] + TestTypeOf() cil managed + { + // Code size 116 (0x74) + .maxstack 4 + .locals init (class [mscorlib]System.Type[] V_0) + IL_0000: nop + IL_0001: ldc.i4.8 + IL_0002: newarr [mscorlib]System.Type + IL_0007: dup + IL_0008: ldc.i4.0 + IL_0009: ldtoken [mscorlib]System.Int32 + IL_000e: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) + IL_0013: stelem.ref + IL_0014: dup + IL_0015: ldc.i4.1 + IL_0016: ldtoken int32[] + IL_001b: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) + IL_0020: stelem.ref + IL_0021: dup + IL_0022: ldc.i4.2 + IL_0023: ldtoken ICSharpCode.Decompiler.Tests.TestCases.Pretty.Generics/GenericClass`1 + IL_0028: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) + IL_002d: stelem.ref + IL_002e: dup + IL_002f: ldc.i4.3 + IL_0030: ldtoken class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Generics/GenericClass`1 + IL_0035: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) + IL_003a: stelem.ref + IL_003b: dup + IL_003c: ldc.i4.4 + IL_003d: ldtoken class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Generics/GenericClass`1 + IL_0042: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) + IL_0047: stelem.ref + IL_0048: dup + IL_0049: ldc.i4.5 + IL_004a: ldtoken [mscorlib]System.Collections.Generic.Dictionary`2 + IL_004f: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) + IL_0054: stelem.ref + IL_0055: dup + IL_0056: ldc.i4.6 + IL_0057: ldtoken valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator + IL_005c: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) + IL_0061: stelem.ref + IL_0062: dup + IL_0063: ldc.i4.7 + IL_0064: ldtoken [mscorlib]System.Collections.Generic.List`1/Enumerator + IL_0069: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) + IL_006e: stelem.ref + IL_006f: stloc.0 + IL_0070: br.s IL_0072 + + IL_0072: ldloc.0 + IL_0073: ret + } // end of method Generics::TestTypeOf + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.cs index ebcf87829..37a16167d 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.cs @@ -213,6 +213,25 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty select (x); } + public static IEnumerable Issue1310a(bool test) + { +#if ROSLYN && OPT + IEnumerable obj = test ? (from c in Enumerable.Range(0, 255) + where char.IsLetter((char)c) + select (char)c) : (from c in Enumerable.Range(0, 255) + where char.IsDigit((char)c) + select (char)c); + return obj.Concat(obj); +#else + IEnumerable enumerable = test ? (from c in Enumerable.Range(0, 255) + where char.IsLetter((char)c) + select (char)c) : (from c in Enumerable.Range(0, 255) + where char.IsDigit((char)c) + select (char)c); + return enumerable.Concat(enumerable); +#endif + } + public static Maybe Cast(Maybe a) where TB : class { return from m in a diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.il index a73a6d0ea..2aa36ab3a 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.il @@ -17,8 +17,8 @@ { .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows. - .custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) .permissionset reqmin = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}} .hash algorithm 0x00008004 @@ -273,6 +273,14 @@ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .field private static class [mscorlib]System.Func`2 'CS$<>9__CachedAnonymousMethodDelegate6a' .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private static class [mscorlib]System.Func`2 'CS$<>9__CachedAnonymousMethodDelegate6f' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private static class [mscorlib]System.Func`2 'CS$<>9__CachedAnonymousMethodDelegate70' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private static class [mscorlib]System.Func`2 'CS$<>9__CachedAnonymousMethodDelegate71' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private static class [mscorlib]System.Func`2 'CS$<>9__CachedAnonymousMethodDelegate72' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .method public hidebysig instance object MultipleWhere() cil managed { @@ -1097,6 +1105,92 @@ IL_004e: ret } // end of method QueryExpressions::Issue437 + .method public hidebysig static class [mscorlib]System.Collections.Generic.IEnumerable`1 + Issue1310a(bool test) cil managed + { + // Code size 186 (0xba) + .maxstack 3 + .locals init (class [mscorlib]System.Collections.Generic.IEnumerable`1 V_0, + class [mscorlib]System.Collections.Generic.IEnumerable`1 V_1) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: brtrue.s IL_0059 + + IL_0004: ldc.i4.0 + IL_0005: ldc.i4 0xff + IL_000a: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Range(int32, + int32) + IL_000f: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate71' + IL_0014: brtrue.s IL_0029 + + IL_0016: ldnull + IL_0017: ldftn bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'b__6d'(int32) + IL_001d: newobj instance void class [mscorlib]System.Func`2::.ctor(object, + native int) + IL_0022: stsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate71' + IL_0027: br.s IL_0029 + + IL_0029: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate71' + IL_002e: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Where(class [mscorlib]System.Collections.Generic.IEnumerable`1, + class [mscorlib]System.Func`2) + IL_0033: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate72' + IL_0038: brtrue.s IL_004d + + IL_003a: ldnull + IL_003b: ldftn char ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'b__6e'(int32) + IL_0041: newobj instance void class [mscorlib]System.Func`2::.ctor(object, + native int) + IL_0046: stsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate72' + IL_004b: br.s IL_004d + + IL_004d: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate72' + IL_0052: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Select(class [mscorlib]System.Collections.Generic.IEnumerable`1, + class [mscorlib]System.Func`2) + IL_0057: br.s IL_00ac + + IL_0059: ldc.i4.0 + IL_005a: ldc.i4 0xff + IL_005f: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Range(int32, + int32) + IL_0064: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate6f' + IL_0069: brtrue.s IL_007e + + IL_006b: ldnull + IL_006c: ldftn bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'b__6b'(int32) + IL_0072: newobj instance void class [mscorlib]System.Func`2::.ctor(object, + native int) + IL_0077: stsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate6f' + IL_007c: br.s IL_007e + + IL_007e: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate6f' + IL_0083: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Where(class [mscorlib]System.Collections.Generic.IEnumerable`1, + class [mscorlib]System.Func`2) + IL_0088: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate70' + IL_008d: brtrue.s IL_00a2 + + IL_008f: ldnull + IL_0090: ldftn char ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'b__6c'(int32) + IL_0096: newobj instance void class [mscorlib]System.Func`2::.ctor(object, + native int) + IL_009b: stsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate70' + IL_00a0: br.s IL_00a2 + + IL_00a2: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate70' + IL_00a7: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Select(class [mscorlib]System.Collections.Generic.IEnumerable`1, + class [mscorlib]System.Func`2) + IL_00ac: nop + IL_00ad: stloc.0 + IL_00ae: ldloc.0 + IL_00af: ldloc.0 + IL_00b0: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Concat(class [mscorlib]System.Collections.Generic.IEnumerable`1, + class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_00b5: stloc.1 + IL_00b6: br.s IL_00b8 + + IL_00b8: ldloc.1 + IL_00b9: ret + } // end of method QueryExpressions::Issue1310a + .method public hidebysig static valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1 Cast(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1 a) cil managed { @@ -1106,19 +1200,19 @@ IL_0000: nop IL_0001: ldarg.0 IL_0002: ldnull - IL_0003: ldftn class '<>f__AnonymousType11`2' ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'b__6c'(!!0) + IL_0003: ldftn class '<>f__AnonymousType11`2' ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'b__74'(!!0) IL_0009: newobj instance void class [mscorlib]System.Func`2f__AnonymousType11`2'>::.ctor(object, native int) IL_000e: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.MaybeExtensions::Selectf__AnonymousType11`2'>(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1, class [mscorlib]System.Func`2) IL_0013: ldnull - IL_0014: ldftn bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'b__6d'(class '<>f__AnonymousType11`2') + IL_0014: ldftn bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'b__75'(class '<>f__AnonymousType11`2') IL_001a: newobj instance void class [mscorlib]System.Func`2f__AnonymousType11`2',bool>::.ctor(object, native int) IL_001f: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.MaybeExtensions::Wheref__AnonymousType11`2'>(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1, class [mscorlib]System.Func`2) IL_0024: ldnull - IL_0025: ldftn !!1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'b__6e'(class '<>f__AnonymousType11`2') + IL_0025: ldftn !!1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'b__76'(class '<>f__AnonymousType11`2') IL_002b: newobj instance void class [mscorlib]System.Func`2f__AnonymousType11`2',!!TB>::.ctor(object, native int) IL_0030: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.MaybeExtensions::Selectf__AnonymousType11`2',!!1>(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1, @@ -2055,8 +2149,70 @@ IL_0005: ret } // end of method QueryExpressions::'b__68' + .method private hidebysig static bool 'b__6b'(int32 c) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 12 (0xc) + .maxstack 1 + .locals init (bool V_0) + IL_0000: ldarg.0 + IL_0001: conv.u2 + IL_0002: call bool [mscorlib]System.Char::IsLetter(char) + IL_0007: stloc.0 + IL_0008: br.s IL_000a + + IL_000a: ldloc.0 + IL_000b: ret + } // end of method QueryExpressions::'b__6b' + + .method private hidebysig static char 'b__6c'(int32 c) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 1 + .locals init (char V_0) + IL_0000: ldarg.0 + IL_0001: conv.u2 + IL_0002: stloc.0 + IL_0003: br.s IL_0005 + + IL_0005: ldloc.0 + IL_0006: ret + } // end of method QueryExpressions::'b__6c' + + .method private hidebysig static bool 'b__6d'(int32 c) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 12 (0xc) + .maxstack 1 + .locals init (bool V_0) + IL_0000: ldarg.0 + IL_0001: conv.u2 + IL_0002: call bool [mscorlib]System.Char::IsDigit(char) + IL_0007: stloc.0 + IL_0008: br.s IL_000a + + IL_000a: ldloc.0 + IL_000b: ret + } // end of method QueryExpressions::'b__6d' + + .method private hidebysig static char 'b__6e'(int32 c) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 1 + .locals init (char V_0) + IL_0000: ldarg.0 + IL_0001: conv.u2 + IL_0002: stloc.0 + IL_0003: br.s IL_0005 + + IL_0005: ldloc.0 + IL_0006: ret + } // end of method QueryExpressions::'b__6e' + .method private hidebysig static class '<>f__AnonymousType11`2' - 'b__6c'(!!TA m) cil managed + 'b__74'(!!TA m) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) // Code size 27 (0x1b) @@ -2074,9 +2230,9 @@ IL_0019: ldloc.0 IL_001a: ret - } // end of method QueryExpressions::'b__6c' + } // end of method QueryExpressions::'b__74' - .method private hidebysig static bool 'b__6d'(class '<>f__AnonymousType11`2' '<>h__TransparentIdentifier6b') cil managed + .method private hidebysig static bool 'b__75'(class '<>f__AnonymousType11`2' '<>h__TransparentIdentifier73') cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) // Code size 22 (0x16) @@ -2094,9 +2250,9 @@ IL_0014: ldloc.0 IL_0015: ret - } // end of method QueryExpressions::'b__6d' + } // end of method QueryExpressions::'b__75' - .method private hidebysig static !!TB 'b__6e'(class '<>f__AnonymousType11`2' '<>h__TransparentIdentifier6b') cil managed + .method private hidebysig static !!TB 'b__76'(class '<>f__AnonymousType11`2' '<>h__TransparentIdentifier73') cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) // Code size 11 (0xb) @@ -2109,7 +2265,7 @@ IL_0009: ldloc.0 IL_000a: ret - } // end of method QueryExpressions::'b__6e' + } // end of method QueryExpressions::'b__76' } // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.opt.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.opt.il index 487f6754b..4997aebba 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.opt.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.opt.il @@ -17,8 +17,8 @@ { .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows. - .custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) .permissionset reqmin = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}} .hash algorithm 0x00008004 @@ -263,6 +263,14 @@ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .field private static class [mscorlib]System.Func`2 'CS$<>9__CachedAnonymousMethodDelegate6a' .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private static class [mscorlib]System.Func`2 'CS$<>9__CachedAnonymousMethodDelegate6f' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private static class [mscorlib]System.Func`2 'CS$<>9__CachedAnonymousMethodDelegate70' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private static class [mscorlib]System.Func`2 'CS$<>9__CachedAnonymousMethodDelegate71' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private static class [mscorlib]System.Func`2 'CS$<>9__CachedAnonymousMethodDelegate72' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .method public hidebysig instance object MultipleWhere() cil managed { @@ -909,6 +917,77 @@ IL_0045: ret } // end of method QueryExpressions::Issue437 + .method public hidebysig static class [mscorlib]System.Collections.Generic.IEnumerable`1 + Issue1310a(bool test) cil managed + { + // Code size 172 (0xac) + .maxstack 3 + .locals init (class [mscorlib]System.Collections.Generic.IEnumerable`1 V_0) + IL_0000: ldarg.0 + IL_0001: brtrue.s IL_0054 + + IL_0003: ldc.i4.0 + IL_0004: ldc.i4 0xff + IL_0009: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Range(int32, + int32) + IL_000e: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate71' + IL_0013: brtrue.s IL_0026 + + IL_0015: ldnull + IL_0016: ldftn bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'b__6d'(int32) + IL_001c: newobj instance void class [mscorlib]System.Func`2::.ctor(object, + native int) + IL_0021: stsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate71' + IL_0026: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate71' + IL_002b: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Where(class [mscorlib]System.Collections.Generic.IEnumerable`1, + class [mscorlib]System.Func`2) + IL_0030: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate72' + IL_0035: brtrue.s IL_0048 + + IL_0037: ldnull + IL_0038: ldftn char ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'b__6e'(int32) + IL_003e: newobj instance void class [mscorlib]System.Func`2::.ctor(object, + native int) + IL_0043: stsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate72' + IL_0048: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate72' + IL_004d: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Select(class [mscorlib]System.Collections.Generic.IEnumerable`1, + class [mscorlib]System.Func`2) + IL_0052: br.s IL_00a3 + + IL_0054: ldc.i4.0 + IL_0055: ldc.i4 0xff + IL_005a: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Range(int32, + int32) + IL_005f: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate6f' + IL_0064: brtrue.s IL_0077 + + IL_0066: ldnull + IL_0067: ldftn bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'b__6b'(int32) + IL_006d: newobj instance void class [mscorlib]System.Func`2::.ctor(object, + native int) + IL_0072: stsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate6f' + IL_0077: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate6f' + IL_007c: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Where(class [mscorlib]System.Collections.Generic.IEnumerable`1, + class [mscorlib]System.Func`2) + IL_0081: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate70' + IL_0086: brtrue.s IL_0099 + + IL_0088: ldnull + IL_0089: ldftn char ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'b__6c'(int32) + IL_008f: newobj instance void class [mscorlib]System.Func`2::.ctor(object, + native int) + IL_0094: stsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate70' + IL_0099: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'CS$<>9__CachedAnonymousMethodDelegate70' + IL_009e: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Select(class [mscorlib]System.Collections.Generic.IEnumerable`1, + class [mscorlib]System.Func`2) + IL_00a3: stloc.0 + IL_00a4: ldloc.0 + IL_00a5: ldloc.0 + IL_00a6: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Concat(class [mscorlib]System.Collections.Generic.IEnumerable`1, + class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_00ab: ret + } // end of method QueryExpressions::Issue1310a + .method public hidebysig static valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1 Cast(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1 a) cil managed { @@ -916,19 +995,19 @@ .maxstack 8 IL_0000: ldarg.0 IL_0001: ldnull - IL_0002: ldftn class '<>f__AnonymousType11`2' ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'b__6c'(!!0) + IL_0002: ldftn class '<>f__AnonymousType11`2' ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'b__74'(!!0) IL_0008: newobj instance void class [mscorlib]System.Func`2f__AnonymousType11`2'>::.ctor(object, native int) IL_000d: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.MaybeExtensions::Selectf__AnonymousType11`2'>(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1, class [mscorlib]System.Func`2) IL_0012: ldnull - IL_0013: ldftn bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'b__6d'(class '<>f__AnonymousType11`2') + IL_0013: ldftn bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'b__75'(class '<>f__AnonymousType11`2') IL_0019: newobj instance void class [mscorlib]System.Func`2f__AnonymousType11`2',bool>::.ctor(object, native int) IL_001e: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.MaybeExtensions::Wheref__AnonymousType11`2'>(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1, class [mscorlib]System.Func`2) IL_0023: ldnull - IL_0024: ldftn !!1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'b__6e'(class '<>f__AnonymousType11`2') + IL_0024: ldftn !!1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions::'b__76'(class '<>f__AnonymousType11`2') IL_002a: newobj instance void class [mscorlib]System.Func`2f__AnonymousType11`2',!!TB>::.ctor(object, native int) IL_002f: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.MaybeExtensions::Selectf__AnonymousType11`2',!!1>(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1, @@ -1626,8 +1705,50 @@ IL_0001: ret } // end of method QueryExpressions::'b__68' + .method private hidebysig static bool 'b__6b'(int32 c) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: conv.u2 + IL_0002: call bool [mscorlib]System.Char::IsLetter(char) + IL_0007: ret + } // end of method QueryExpressions::'b__6b' + + .method private hidebysig static char 'b__6c'(int32 c) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 3 (0x3) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: conv.u2 + IL_0002: ret + } // end of method QueryExpressions::'b__6c' + + .method private hidebysig static bool 'b__6d'(int32 c) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: conv.u2 + IL_0002: call bool [mscorlib]System.Char::IsDigit(char) + IL_0007: ret + } // end of method QueryExpressions::'b__6d' + + .method private hidebysig static char 'b__6e'(int32 c) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 3 (0x3) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: conv.u2 + IL_0002: ret + } // end of method QueryExpressions::'b__6e' + .method private hidebysig static class '<>f__AnonymousType11`2' - 'b__6c'(!!TA m) cil managed + 'b__74'(!!TA m) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) // Code size 23 (0x17) @@ -1640,9 +1761,9 @@ IL_0011: newobj instance void class '<>f__AnonymousType11`2'::.ctor(!0, !1) IL_0016: ret - } // end of method QueryExpressions::'b__6c' + } // end of method QueryExpressions::'b__74' - .method private hidebysig static bool 'b__6d'(class '<>f__AnonymousType11`2' '<>h__TransparentIdentifier6b') cil managed + .method private hidebysig static bool 'b__75'(class '<>f__AnonymousType11`2' '<>h__TransparentIdentifier73') cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) // Code size 18 (0x12) @@ -1655,9 +1776,9 @@ IL_000e: ldc.i4.0 IL_000f: ceq IL_0011: ret - } // end of method QueryExpressions::'b__6d' + } // end of method QueryExpressions::'b__75' - .method private hidebysig static !!TB 'b__6e'(class '<>f__AnonymousType11`2' '<>h__TransparentIdentifier6b') cil managed + .method private hidebysig static !!TB 'b__76'(class '<>f__AnonymousType11`2' '<>h__TransparentIdentifier73') cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) // Code size 7 (0x7) @@ -1665,7 +1786,7 @@ IL_0000: ldarg.0 IL_0001: callvirt instance !1 class '<>f__AnonymousType11`2'::get_t() IL_0006: ret - } // end of method QueryExpressions::'b__6e' + } // end of method QueryExpressions::'b__76' } // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.opt.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.opt.roslyn.il index f1e4543e1..91a5ac863 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.opt.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.opt.roslyn.il @@ -3857,6 +3857,10 @@ .field public static class [mscorlib]System.Func`2,class '<>f__AnonymousType16`2'> '<>9__19_1' .field public static class [mscorlib]System.Func`2 '<>9__20_0' .field public static class [mscorlib]System.Func`2 '<>9__20_1' + .field public static class [mscorlib]System.Func`2 '<>9__21_0' + .field public static class [mscorlib]System.Func`2 '<>9__21_1' + .field public static class [mscorlib]System.Func`2 '<>9__21_2' + .field public static class [mscorlib]System.Func`2 '<>9__21_3' .method private hidebysig specialname rtspecialname static void .cctor() cil managed { @@ -4499,25 +4503,67 @@ IL_0001: ret } // end of method '<>c'::'b__20_1' + .method assembly hidebysig instance bool + 'b__21_0'(int32 c) cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: conv.u2 + IL_0002: call bool [mscorlib]System.Char::IsLetter(char) + IL_0007: ret + } // end of method '<>c'::'b__21_0' + + .method assembly hidebysig instance char + 'b__21_1'(int32 c) cil managed + { + // Code size 3 (0x3) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: conv.u2 + IL_0002: ret + } // end of method '<>c'::'b__21_1' + + .method assembly hidebysig instance bool + 'b__21_2'(int32 c) cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: conv.u2 + IL_0002: call bool [mscorlib]System.Char::IsDigit(char) + IL_0007: ret + } // end of method '<>c'::'b__21_2' + + .method assembly hidebysig instance char + 'b__21_3'(int32 c) cil managed + { + // Code size 3 (0x3) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: conv.u2 + IL_0002: ret + } // end of method '<>c'::'b__21_3' + } // end of class '<>c' - .class auto ansi serializable sealed nested private beforefieldinit '<>c__21`2' + .class auto ansi serializable sealed nested private beforefieldinit '<>c__22`2' extends [mscorlib]System.Object { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .field public static initonly class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2' '<>9' - .field public static class [mscorlib]System.Func`2f__AnonymousType17`2'> '<>9__21_0' - .field public static class [mscorlib]System.Func`2f__AnonymousType17`2',bool> '<>9__21_1' - .field public static class [mscorlib]System.Func`2f__AnonymousType17`2',!TB> '<>9__21_2' + .field public static initonly class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2' '<>9' + .field public static class [mscorlib]System.Func`2f__AnonymousType17`2'> '<>9__22_0' + .field public static class [mscorlib]System.Func`2f__AnonymousType17`2',bool> '<>9__22_1' + .field public static class [mscorlib]System.Func`2f__AnonymousType17`2',!TB> '<>9__22_2' .method private hidebysig specialname rtspecialname static void .cctor() cil managed { // Code size 11 (0xb) .maxstack 8 - IL_0000: newobj instance void class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'::.ctor() - IL_0005: stsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2' class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'::'<>9' + IL_0000: newobj instance void class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'::.ctor() + IL_0005: stsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2' class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'::'<>9' IL_000a: ret - } // end of method '<>c__21`2'::.cctor + } // end of method '<>c__22`2'::.cctor .method public hidebysig specialname rtspecialname instance void .ctor() cil managed @@ -4527,10 +4573,10 @@ IL_0000: ldarg.0 IL_0001: call instance void [mscorlib]System.Object::.ctor() IL_0006: ret - } // end of method '<>c__21`2'::.ctor + } // end of method '<>c__22`2'::.ctor .method assembly hidebysig instance class '<>f__AnonymousType17`2' - 'b__21_0'(!TA m) cil managed + 'b__22_0'(!TA m) cil managed { // Code size 23 (0x17) .maxstack 8 @@ -4542,10 +4588,10 @@ IL_0011: newobj instance void class '<>f__AnonymousType17`2'::.ctor(!0, !1) IL_0016: ret - } // end of method '<>c__21`2'::'b__21_0' + } // end of method '<>c__22`2'::'b__22_0' .method assembly hidebysig instance bool - 'b__21_1'(class '<>f__AnonymousType17`2' '<>h__TransparentIdentifier0') cil managed + 'b__22_1'(class '<>f__AnonymousType17`2' '<>h__TransparentIdentifier0') cil managed { // Code size 15 (0xf) .maxstack 8 @@ -4555,19 +4601,19 @@ IL_000b: ldnull IL_000c: cgt.un IL_000e: ret - } // end of method '<>c__21`2'::'b__21_1' + } // end of method '<>c__22`2'::'b__22_1' .method assembly hidebysig instance !TB - 'b__21_2'(class '<>f__AnonymousType17`2' '<>h__TransparentIdentifier0') cil managed + 'b__22_2'(class '<>f__AnonymousType17`2' '<>h__TransparentIdentifier0') cil managed { // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.1 IL_0001: callvirt instance !1 class '<>f__AnonymousType17`2'::get_t() IL_0006: ret - } // end of method '<>c__21`2'::'b__21_2' + } // end of method '<>c__22`2'::'b__22_2' - } // end of class '<>c__21`2' + } // end of class '<>c__22`2' .field public class [mscorlib]System.Collections.Generic.IEnumerable`1 customers .field public class [mscorlib]System.Collections.Generic.IEnumerable`1 orders @@ -5305,49 +5351,125 @@ IL_0049: ret } // end of method QueryExpressions::Issue437 + .method public hidebysig static class [mscorlib]System.Collections.Generic.IEnumerable`1 + Issue1310a(bool test) cil managed + { + // Code size 178 (0xb2) + .maxstack 3 + IL_0000: ldarg.0 + IL_0001: brtrue.s IL_0058 + + IL_0003: ldc.i4.0 + IL_0004: ldc.i4 0xff + IL_0009: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Range(int32, + int32) + IL_000e: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9__21_2' + IL_0013: dup + IL_0014: brtrue.s IL_002d + + IL_0016: pop + IL_0017: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c' ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9' + IL_001c: ldftn instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'b__21_2'(int32) + IL_0022: newobj instance void class [mscorlib]System.Func`2::.ctor(object, + native int) + IL_0027: dup + IL_0028: stsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9__21_2' + IL_002d: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Where(class [mscorlib]System.Collections.Generic.IEnumerable`1, + class [mscorlib]System.Func`2) + IL_0032: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9__21_3' + IL_0037: dup + IL_0038: brtrue.s IL_0051 + + IL_003a: pop + IL_003b: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c' ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9' + IL_0040: ldftn instance char ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'b__21_3'(int32) + IL_0046: newobj instance void class [mscorlib]System.Func`2::.ctor(object, + native int) + IL_004b: dup + IL_004c: stsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9__21_3' + IL_0051: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Select(class [mscorlib]System.Collections.Generic.IEnumerable`1, + class [mscorlib]System.Func`2) + IL_0056: br.s IL_00ab + + IL_0058: ldc.i4.0 + IL_0059: ldc.i4 0xff + IL_005e: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Range(int32, + int32) + IL_0063: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9__21_0' + IL_0068: dup + IL_0069: brtrue.s IL_0082 + + IL_006b: pop + IL_006c: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c' ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9' + IL_0071: ldftn instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'b__21_0'(int32) + IL_0077: newobj instance void class [mscorlib]System.Func`2::.ctor(object, + native int) + IL_007c: dup + IL_007d: stsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9__21_0' + IL_0082: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Where(class [mscorlib]System.Collections.Generic.IEnumerable`1, + class [mscorlib]System.Func`2) + IL_0087: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9__21_1' + IL_008c: dup + IL_008d: brtrue.s IL_00a6 + + IL_008f: pop + IL_0090: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c' ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9' + IL_0095: ldftn instance char ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'b__21_1'(int32) + IL_009b: newobj instance void class [mscorlib]System.Func`2::.ctor(object, + native int) + IL_00a0: dup + IL_00a1: stsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9__21_1' + IL_00a6: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Select(class [mscorlib]System.Collections.Generic.IEnumerable`1, + class [mscorlib]System.Func`2) + IL_00ab: dup + IL_00ac: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Concat(class [mscorlib]System.Collections.Generic.IEnumerable`1, + class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_00b1: ret + } // end of method QueryExpressions::Issue1310a + .method public hidebysig static valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1 Cast(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1 a) cil managed { // Code size 110 (0x6e) .maxstack 3 IL_0000: ldarg.0 - IL_0001: ldsfld class [mscorlib]System.Func`2f__AnonymousType17`2'> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'::'<>9__21_0' + IL_0001: ldsfld class [mscorlib]System.Func`2f__AnonymousType17`2'> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'::'<>9__22_0' IL_0006: dup IL_0007: brtrue.s IL_0020 IL_0009: pop - IL_000a: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2' class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'::'<>9' - IL_000f: ldftn instance class '<>f__AnonymousType17`2' class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'::'b__21_0'(!0) + IL_000a: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2' class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'::'<>9' + IL_000f: ldftn instance class '<>f__AnonymousType17`2' class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'::'b__22_0'(!0) IL_0015: newobj instance void class [mscorlib]System.Func`2f__AnonymousType17`2'>::.ctor(object, native int) IL_001a: dup - IL_001b: stsfld class [mscorlib]System.Func`2f__AnonymousType17`2'> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'::'<>9__21_0' + IL_001b: stsfld class [mscorlib]System.Func`2f__AnonymousType17`2'> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'::'<>9__22_0' IL_0020: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.MaybeExtensions::Selectf__AnonymousType17`2'>(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1, class [mscorlib]System.Func`2) - IL_0025: ldsfld class [mscorlib]System.Func`2f__AnonymousType17`2',bool> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'::'<>9__21_1' + IL_0025: ldsfld class [mscorlib]System.Func`2f__AnonymousType17`2',bool> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'::'<>9__22_1' IL_002a: dup IL_002b: brtrue.s IL_0044 IL_002d: pop - IL_002e: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2' class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'::'<>9' - IL_0033: ldftn instance bool class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'::'b__21_1'(class '<>f__AnonymousType17`2') + IL_002e: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2' class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'::'<>9' + IL_0033: ldftn instance bool class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'::'b__22_1'(class '<>f__AnonymousType17`2') IL_0039: newobj instance void class [mscorlib]System.Func`2f__AnonymousType17`2',bool>::.ctor(object, native int) IL_003e: dup - IL_003f: stsfld class [mscorlib]System.Func`2f__AnonymousType17`2',bool> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'::'<>9__21_1' + IL_003f: stsfld class [mscorlib]System.Func`2f__AnonymousType17`2',bool> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'::'<>9__22_1' IL_0044: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.MaybeExtensions::Wheref__AnonymousType17`2'>(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1, class [mscorlib]System.Func`2) - IL_0049: ldsfld class [mscorlib]System.Func`2f__AnonymousType17`2',!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'::'<>9__21_2' + IL_0049: ldsfld class [mscorlib]System.Func`2f__AnonymousType17`2',!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'::'<>9__22_2' IL_004e: dup IL_004f: brtrue.s IL_0068 IL_0051: pop - IL_0052: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2' class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'::'<>9' - IL_0057: ldftn instance !1 class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'::'b__21_2'(class '<>f__AnonymousType17`2') + IL_0052: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2' class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'::'<>9' + IL_0057: ldftn instance !1 class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'::'b__22_2'(class '<>f__AnonymousType17`2') IL_005d: newobj instance void class [mscorlib]System.Func`2f__AnonymousType17`2',!!TB>::.ctor(object, native int) IL_0062: dup - IL_0063: stsfld class [mscorlib]System.Func`2f__AnonymousType17`2',!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'::'<>9__21_2' + IL_0063: stsfld class [mscorlib]System.Func`2f__AnonymousType17`2',!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'::'<>9__22_2' IL_0068: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.MaybeExtensions::Selectf__AnonymousType17`2',!!1>(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1, class [mscorlib]System.Func`2) IL_006d: ret diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.roslyn.il index fe6097b4f..72381673d 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.roslyn.il @@ -3960,6 +3960,10 @@ .field public static class [mscorlib]System.Func`2,class '<>f__AnonymousType16`2'> '<>9__19_1' .field public static class [mscorlib]System.Func`2 '<>9__20_0' .field public static class [mscorlib]System.Func`2 '<>9__20_1' + .field public static class [mscorlib]System.Func`2 '<>9__21_0' + .field public static class [mscorlib]System.Func`2 '<>9__21_1' + .field public static class [mscorlib]System.Func`2 '<>9__21_2' + .field public static class [mscorlib]System.Func`2 '<>9__21_3' .method private hidebysig specialname rtspecialname static void .cctor() cil managed { @@ -4605,25 +4609,67 @@ IL_0001: ret } // end of method '<>c'::'b__20_1' + .method assembly hidebysig instance bool + 'b__21_0'(int32 c) cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: conv.u2 + IL_0002: call bool [mscorlib]System.Char::IsLetter(char) + IL_0007: ret + } // end of method '<>c'::'b__21_0' + + .method assembly hidebysig instance char + 'b__21_1'(int32 c) cil managed + { + // Code size 3 (0x3) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: conv.u2 + IL_0002: ret + } // end of method '<>c'::'b__21_1' + + .method assembly hidebysig instance bool + 'b__21_2'(int32 c) cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: conv.u2 + IL_0002: call bool [mscorlib]System.Char::IsDigit(char) + IL_0007: ret + } // end of method '<>c'::'b__21_2' + + .method assembly hidebysig instance char + 'b__21_3'(int32 c) cil managed + { + // Code size 3 (0x3) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: conv.u2 + IL_0002: ret + } // end of method '<>c'::'b__21_3' + } // end of class '<>c' - .class auto ansi serializable sealed nested private beforefieldinit '<>c__21`2' + .class auto ansi serializable sealed nested private beforefieldinit '<>c__22`2' extends [mscorlib]System.Object { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .field public static initonly class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2' '<>9' - .field public static class [mscorlib]System.Func`2f__AnonymousType17`2'> '<>9__21_0' - .field public static class [mscorlib]System.Func`2f__AnonymousType17`2',bool> '<>9__21_1' - .field public static class [mscorlib]System.Func`2f__AnonymousType17`2',!TB> '<>9__21_2' + .field public static initonly class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2' '<>9' + .field public static class [mscorlib]System.Func`2f__AnonymousType17`2'> '<>9__22_0' + .field public static class [mscorlib]System.Func`2f__AnonymousType17`2',bool> '<>9__22_1' + .field public static class [mscorlib]System.Func`2f__AnonymousType17`2',!TB> '<>9__22_2' .method private hidebysig specialname rtspecialname static void .cctor() cil managed { // Code size 11 (0xb) .maxstack 8 - IL_0000: newobj instance void class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'::.ctor() - IL_0005: stsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2' class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'::'<>9' + IL_0000: newobj instance void class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'::.ctor() + IL_0005: stsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2' class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'::'<>9' IL_000a: ret - } // end of method '<>c__21`2'::.cctor + } // end of method '<>c__22`2'::.cctor .method public hidebysig specialname rtspecialname instance void .ctor() cil managed @@ -4634,10 +4680,10 @@ IL_0001: call instance void [mscorlib]System.Object::.ctor() IL_0006: nop IL_0007: ret - } // end of method '<>c__21`2'::.ctor + } // end of method '<>c__22`2'::.ctor .method assembly hidebysig instance class '<>f__AnonymousType17`2' - 'b__21_0'(!TA m) cil managed + 'b__22_0'(!TA m) cil managed { // Code size 23 (0x17) .maxstack 8 @@ -4649,10 +4695,10 @@ IL_0011: newobj instance void class '<>f__AnonymousType17`2'::.ctor(!0, !1) IL_0016: ret - } // end of method '<>c__21`2'::'b__21_0' + } // end of method '<>c__22`2'::'b__22_0' .method assembly hidebysig instance bool - 'b__21_1'(class '<>f__AnonymousType17`2' '<>h__TransparentIdentifier0') cil managed + 'b__22_1'(class '<>f__AnonymousType17`2' '<>h__TransparentIdentifier0') cil managed { // Code size 15 (0xf) .maxstack 8 @@ -4662,19 +4708,19 @@ IL_000b: ldnull IL_000c: cgt.un IL_000e: ret - } // end of method '<>c__21`2'::'b__21_1' + } // end of method '<>c__22`2'::'b__22_1' .method assembly hidebysig instance !TB - 'b__21_2'(class '<>f__AnonymousType17`2' '<>h__TransparentIdentifier0') cil managed + 'b__22_2'(class '<>f__AnonymousType17`2' '<>h__TransparentIdentifier0') cil managed { // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.1 IL_0001: callvirt instance !1 class '<>f__AnonymousType17`2'::get_t() IL_0006: ret - } // end of method '<>c__21`2'::'b__21_2' + } // end of method '<>c__22`2'::'b__22_2' - } // end of class '<>c__21`2' + } // end of class '<>c__22`2' .field public class [mscorlib]System.Collections.Generic.IEnumerable`1 customers .field public class [mscorlib]System.Collections.Generic.IEnumerable`1 orders @@ -5502,6 +5548,91 @@ IL_004e: ret } // end of method QueryExpressions::Issue437 + .method public hidebysig static class [mscorlib]System.Collections.Generic.IEnumerable`1 + Issue1310a(bool test) cil managed + { + // Code size 185 (0xb9) + .maxstack 3 + .locals init (class [mscorlib]System.Collections.Generic.IEnumerable`1 V_0, + class [mscorlib]System.Collections.Generic.IEnumerable`1 V_1) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: brtrue.s IL_0059 + + IL_0004: ldc.i4.0 + IL_0005: ldc.i4 0xff + IL_000a: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Range(int32, + int32) + IL_000f: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9__21_2' + IL_0014: dup + IL_0015: brtrue.s IL_002e + + IL_0017: pop + IL_0018: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c' ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9' + IL_001d: ldftn instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'b__21_2'(int32) + IL_0023: newobj instance void class [mscorlib]System.Func`2::.ctor(object, + native int) + IL_0028: dup + IL_0029: stsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9__21_2' + IL_002e: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Where(class [mscorlib]System.Collections.Generic.IEnumerable`1, + class [mscorlib]System.Func`2) + IL_0033: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9__21_3' + IL_0038: dup + IL_0039: brtrue.s IL_0052 + + IL_003b: pop + IL_003c: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c' ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9' + IL_0041: ldftn instance char ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'b__21_3'(int32) + IL_0047: newobj instance void class [mscorlib]System.Func`2::.ctor(object, + native int) + IL_004c: dup + IL_004d: stsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9__21_3' + IL_0052: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Select(class [mscorlib]System.Collections.Generic.IEnumerable`1, + class [mscorlib]System.Func`2) + IL_0057: br.s IL_00ac + + IL_0059: ldc.i4.0 + IL_005a: ldc.i4 0xff + IL_005f: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Range(int32, + int32) + IL_0064: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9__21_0' + IL_0069: dup + IL_006a: brtrue.s IL_0083 + + IL_006c: pop + IL_006d: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c' ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9' + IL_0072: ldftn instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'b__21_0'(int32) + IL_0078: newobj instance void class [mscorlib]System.Func`2::.ctor(object, + native int) + IL_007d: dup + IL_007e: stsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9__21_0' + IL_0083: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Where(class [mscorlib]System.Collections.Generic.IEnumerable`1, + class [mscorlib]System.Func`2) + IL_0088: ldsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9__21_1' + IL_008d: dup + IL_008e: brtrue.s IL_00a7 + + IL_0090: pop + IL_0091: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c' ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9' + IL_0096: ldftn instance char ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'b__21_1'(int32) + IL_009c: newobj instance void class [mscorlib]System.Func`2::.ctor(object, + native int) + IL_00a1: dup + IL_00a2: stsfld class [mscorlib]System.Func`2 ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c'::'<>9__21_1' + IL_00a7: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Select(class [mscorlib]System.Collections.Generic.IEnumerable`1, + class [mscorlib]System.Func`2) + IL_00ac: stloc.0 + IL_00ad: ldloc.0 + IL_00ae: ldloc.0 + IL_00af: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::Concat(class [mscorlib]System.Collections.Generic.IEnumerable`1, + class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_00b4: stloc.1 + IL_00b5: br.s IL_00b7 + + IL_00b7: ldloc.1 + IL_00b8: ret + } // end of method QueryExpressions::Issue1310a + .method public hidebysig static valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1 Cast(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1 a) cil managed { @@ -5510,43 +5641,43 @@ .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1 V_0) IL_0000: nop IL_0001: ldarg.0 - IL_0002: ldsfld class [mscorlib]System.Func`2f__AnonymousType17`2'> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'::'<>9__21_0' + IL_0002: ldsfld class [mscorlib]System.Func`2f__AnonymousType17`2'> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'::'<>9__22_0' IL_0007: dup IL_0008: brtrue.s IL_0021 IL_000a: pop - IL_000b: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2' class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'::'<>9' - IL_0010: ldftn instance class '<>f__AnonymousType17`2' class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'::'b__21_0'(!0) + IL_000b: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2' class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'::'<>9' + IL_0010: ldftn instance class '<>f__AnonymousType17`2' class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'::'b__22_0'(!0) IL_0016: newobj instance void class [mscorlib]System.Func`2f__AnonymousType17`2'>::.ctor(object, native int) IL_001b: dup - IL_001c: stsfld class [mscorlib]System.Func`2f__AnonymousType17`2'> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'::'<>9__21_0' + IL_001c: stsfld class [mscorlib]System.Func`2f__AnonymousType17`2'> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'::'<>9__22_0' IL_0021: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.MaybeExtensions::Selectf__AnonymousType17`2'>(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1, class [mscorlib]System.Func`2) - IL_0026: ldsfld class [mscorlib]System.Func`2f__AnonymousType17`2',bool> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'::'<>9__21_1' + IL_0026: ldsfld class [mscorlib]System.Func`2f__AnonymousType17`2',bool> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'::'<>9__22_1' IL_002b: dup IL_002c: brtrue.s IL_0045 IL_002e: pop - IL_002f: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2' class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'::'<>9' - IL_0034: ldftn instance bool class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'::'b__21_1'(class '<>f__AnonymousType17`2') + IL_002f: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2' class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'::'<>9' + IL_0034: ldftn instance bool class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'::'b__22_1'(class '<>f__AnonymousType17`2') IL_003a: newobj instance void class [mscorlib]System.Func`2f__AnonymousType17`2',bool>::.ctor(object, native int) IL_003f: dup - IL_0040: stsfld class [mscorlib]System.Func`2f__AnonymousType17`2',bool> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'::'<>9__21_1' + IL_0040: stsfld class [mscorlib]System.Func`2f__AnonymousType17`2',bool> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'::'<>9__22_1' IL_0045: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.MaybeExtensions::Wheref__AnonymousType17`2'>(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1, class [mscorlib]System.Func`2) - IL_004a: ldsfld class [mscorlib]System.Func`2f__AnonymousType17`2',!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'::'<>9__21_2' + IL_004a: ldsfld class [mscorlib]System.Func`2f__AnonymousType17`2',!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'::'<>9__22_2' IL_004f: dup IL_0050: brtrue.s IL_0069 IL_0052: pop - IL_0053: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2' class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'::'<>9' - IL_0058: ldftn instance !1 class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'::'b__21_2'(class '<>f__AnonymousType17`2') + IL_0053: ldsfld class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2' class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'::'<>9' + IL_0058: ldftn instance !1 class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'::'b__22_2'(class '<>f__AnonymousType17`2') IL_005e: newobj instance void class [mscorlib]System.Func`2f__AnonymousType17`2',!!TB>::.ctor(object, native int) IL_0063: dup - IL_0064: stsfld class [mscorlib]System.Func`2f__AnonymousType17`2',!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__21`2'::'<>9__21_2' + IL_0064: stsfld class [mscorlib]System.Func`2f__AnonymousType17`2',!1> class ICSharpCode.Decompiler.Tests.TestCases.Pretty.QueryExpressions/'<>c__22`2'::'<>9__22_2' IL_0069: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1 ICSharpCode.Decompiler.Tests.TestCases.Pretty.MaybeExtensions::Selectf__AnonymousType17`2',!!1>(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Maybe`1, class [mscorlib]System.Func`2) IL_006e: stloc.0 diff --git a/ICSharpCode.Decompiler.Tests/UglyTestRunner.cs b/ICSharpCode.Decompiler.Tests/UglyTestRunner.cs index 30230bda5..dff8da418 100644 --- a/ICSharpCode.Decompiler.Tests/UglyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/UglyTestRunner.cs @@ -47,28 +47,28 @@ namespace ICSharpCode.Decompiler.Tests } } - static readonly CSharpCompilerOptions[] noRoslynOptions = + static readonly CompilerOptions[] noRoslynOptions = { - CSharpCompilerOptions.None, - CSharpCompilerOptions.Optimize + CompilerOptions.None, + CompilerOptions.Optimize }; - static readonly CSharpCompilerOptions[] roslynOnlyOptions = + static readonly CompilerOptions[] roslynOnlyOptions = { - CSharpCompilerOptions.UseRoslyn, - CSharpCompilerOptions.Optimize | CSharpCompilerOptions.UseRoslyn + CompilerOptions.UseRoslyn, + CompilerOptions.Optimize | CompilerOptions.UseRoslyn }; - static readonly CSharpCompilerOptions[] defaultOptions = + static readonly CompilerOptions[] defaultOptions = { - CSharpCompilerOptions.None, - CSharpCompilerOptions.Optimize, - CSharpCompilerOptions.UseRoslyn, - CSharpCompilerOptions.Optimize | CSharpCompilerOptions.UseRoslyn + CompilerOptions.None, + CompilerOptions.Optimize, + CompilerOptions.UseRoslyn, + CompilerOptions.Optimize | CompilerOptions.UseRoslyn }; [Test] - public void NoArrayInitializers([ValueSource("roslynOnlyOptions")] CSharpCompilerOptions cscOptions) + public void NoArrayInitializers([ValueSource("roslynOnlyOptions")] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings { ArrayInitializers = false @@ -76,19 +76,19 @@ namespace ICSharpCode.Decompiler.Tests } [Test] - public void NoDecimalConstants([ValueSource("roslynOnlyOptions")] CSharpCompilerOptions cscOptions) + public void NoDecimalConstants([ValueSource("roslynOnlyOptions")] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings { DecimalConstants = false }); } - void RunForLibrary([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CSharpCompilerOptions cscOptions = CSharpCompilerOptions.None, DecompilerSettings decompilerSettings = null) + void RunForLibrary([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CompilerOptions cscOptions = CompilerOptions.None, DecompilerSettings decompilerSettings = null) { - Run(testName, asmOptions | AssemblerOptions.Library, cscOptions | CSharpCompilerOptions.Library, decompilerSettings); + Run(testName, asmOptions | AssemblerOptions.Library, cscOptions | CompilerOptions.Library, decompilerSettings); } - void Run([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CSharpCompilerOptions cscOptions = CSharpCompilerOptions.None, DecompilerSettings decompilerSettings = null) + void Run([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CompilerOptions cscOptions = CompilerOptions.None, DecompilerSettings decompilerSettings = null) { var ilFile = Path.Combine(TestCasePath, testName) + Tester.GetSuffix(cscOptions) + ".il"; var csFile = Path.Combine(TestCasePath, testName + ".cs"); diff --git a/ICSharpCode.Decompiler.Tests/VBPrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/VBPrettyTestRunner.cs index 850edaee0..e8d1d8071 100644 --- a/ICSharpCode.Decompiler.Tests/VBPrettyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/VBPrettyTestRunner.cs @@ -46,27 +46,27 @@ namespace ICSharpCode.Decompiler.Tests } } - static readonly VBCompilerOptions[] defaultOptions = + static readonly CompilerOptions[] defaultOptions = { - VBCompilerOptions.None, - VBCompilerOptions.Optimize, - VBCompilerOptions.UseRoslyn, - VBCompilerOptions.Optimize | VBCompilerOptions.UseRoslyn, + CompilerOptions.None, + CompilerOptions.Optimize, + CompilerOptions.UseRoslyn, + CompilerOptions.Optimize | CompilerOptions.UseRoslyn, }; - static readonly VBCompilerOptions[] roslynOnlyOptions = + static readonly CompilerOptions[] roslynOnlyOptions = { - VBCompilerOptions.UseRoslyn, - VBCompilerOptions.Optimize | VBCompilerOptions.UseRoslyn, + CompilerOptions.UseRoslyn, + CompilerOptions.Optimize | CompilerOptions.UseRoslyn, }; [Test, Ignore("Implement VB async/await")] - public void Async([ValueSource("defaultOptions")] VBCompilerOptions options) + public void Async([ValueSource("defaultOptions")] CompilerOptions options) { Run(options: options); } - void Run([CallerMemberName] string testName = null, VBCompilerOptions options = VBCompilerOptions.UseDebug, DecompilerSettings settings = null) + void Run([CallerMemberName] string testName = null, CompilerOptions options = CompilerOptions.UseDebug, DecompilerSettings settings = null) { var vbFile = Path.Combine(TestCasePath, testName + ".vb"); var csFile = Path.Combine(TestCasePath, testName + ".cs"); diff --git a/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpAmbience.cs b/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpAmbience.cs index a47250675..775cff0b0 100644 --- a/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpAmbience.cs +++ b/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpAmbience.cs @@ -184,6 +184,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor { TypeSystemAstBuilder astBuilder = new TypeSystemAstBuilder(); astBuilder.AddTypeReferenceAnnotations = true; + astBuilder.ShowTypeParametersForUnboundTypes = true; astBuilder.ShowModifiers = (ConversionFlags & ConversionFlags.ShowModifiers) == ConversionFlags.ShowModifiers; astBuilder.ShowAccessibility = (ConversionFlags & ConversionFlags.ShowAccessibility) == ConversionFlags.ShowAccessibility; astBuilder.AlwaysUseShortTypeNames = (ConversionFlags & ConversionFlags.UseFullyQualifiedTypeNames) != ConversionFlags.UseFullyQualifiedTypeNames; diff --git a/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs b/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs index 39b6bef3e..2d96f0afb 100644 --- a/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs +++ b/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs @@ -1141,11 +1141,8 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor public virtual void VisitQueryExpression(QueryExpression queryExpression) { StartNode(queryExpression); - bool indent = queryExpression.Parent is QueryClause && !(queryExpression.Parent is QueryContinuationClause); - if (indent) { + if (queryExpression.Role != QueryContinuationClause.PrecedingQueryRole) writer.Indent(); - NewLine(); - } bool first = true; foreach (var clause in queryExpression.Clauses) { if (first) { @@ -1157,9 +1154,8 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor } clause.AcceptVisitor(this); } - if (indent) { + if (queryExpression.Role != QueryContinuationClause.PrecedingQueryRole) writer.Unindent(); - } EndNode(queryExpression); } diff --git a/ICSharpCode.Decompiler/CSharp/OutputVisitor/TextWriterTokenWriter.cs b/ICSharpCode.Decompiler/CSharp/OutputVisitor/TextWriterTokenWriter.cs index 415c6e881..f25995c8a 100644 --- a/ICSharpCode.Decompiler/CSharp/OutputVisitor/TextWriterTokenWriter.cs +++ b/ICSharpCode.Decompiler/CSharp/OutputVisitor/TextWriterTokenWriter.cs @@ -63,8 +63,9 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor textWriter.Write('@'); column++; } - textWriter.Write(identifier.Name); - column += identifier.Name.Length; + string name = EscapeIdentifier(identifier.Name); + textWriter.Write(name); + column += name.Length; isAtStartOfLine = false; } @@ -417,6 +418,54 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor } return sb.ToString(); } + + public static string EscapeIdentifier(string identifier) + { + if (string.IsNullOrEmpty(identifier)) + return identifier; + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < identifier.Length; i++) { + if (IsPrintableIdentifierChar(identifier, i)) { + if (char.IsSurrogatePair(identifier, i)) { + sb.Append(identifier.Substring(i, 2)); + i++; + } else { + sb.Append(identifier[i]); + } + } else { + if (char.IsSurrogatePair(identifier, i)) { + sb.AppendFormat("\\U{0:x8}", char.ConvertToUtf32(identifier, i)); + i++; + } else { + sb.AppendFormat("\\u{0:x4}", (int)identifier[i]); + } + } + } + return sb.ToString(); + } + + static bool IsPrintableIdentifierChar(string identifier, int index) + { + switch (char.GetUnicodeCategory(identifier, index)) { + case UnicodeCategory.ModifierLetter: + case UnicodeCategory.NonSpacingMark: + case UnicodeCategory.SpacingCombiningMark: + case UnicodeCategory.EnclosingMark: + case UnicodeCategory.LineSeparator: + case UnicodeCategory.ParagraphSeparator: + case UnicodeCategory.Control: + case UnicodeCategory.Format: + case UnicodeCategory.Surrogate: + case UnicodeCategory.PrivateUse: + case UnicodeCategory.ConnectorPunctuation: + case UnicodeCategory.ModifierSymbol: + case UnicodeCategory.OtherNotAssigned: + case UnicodeCategory.SpaceSeparator: + return false; + default: + return true; + } + } public override void WritePrimitiveType(string type) { diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs b/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs index 17dac186b..6c04e4b84 100644 --- a/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs @@ -111,6 +111,12 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax /// The default value is true. /// public bool ShowTypeParameters { get; set; } + + /// + /// Controls whether type parameter names are shown for unbound types. + /// The default value is false. + /// + public bool ShowTypeParametersForUnboundTypes { get; set; } /// /// Controls whether constraints on type parameter declarations are shown. @@ -262,6 +268,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax return astType; } if (type is ITypeDefinition typeDef) { + if (ShowTypeParametersForUnboundTypes) + return ConvertTypeHelper(typeDef, typeDef.TypeArguments); if (typeDef.TypeParameterCount > 0) { // Unbound type IType[] typeArguments = new IType[typeDef.TypeParameterCount]; @@ -272,6 +280,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax } else { return ConvertTypeHelper(typeDef, EmptyList.Instance); } + } return new SimpleType(type.Name); } @@ -742,7 +751,9 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax expression = null; if (!specialConstants.TryGetValue(constant, out var info)) return false; - if (!UseSpecialConstants) { + // if the field definition cannot be found, do not generate a reference to the field. + var field = type.GetFields(p => p.Name == info.Member).SingleOrDefault(); + if (!UseSpecialConstants || field == null) { // +Infty, -Infty and NaN, cannot be represented in their encoded form. // Use an equivalent arithmetic expression instead. if (info.Type == KnownTypeCode.Double) { @@ -800,7 +811,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax expression = new MemberReferenceExpression(expression, info.Member); if (AddResolveResultAnnotations) - expression.AddAnnotation(new MemberResolveResult(new TypeResolveResult(type), type.GetFields(p => p.Name == info.Member).Single())); + expression.AddAnnotation(new MemberResolveResult(new TypeResolveResult(type), field)); return true; } diff --git a/ICSharpCode.Decompiler/CSharp/Transforms/CombineQueryExpressions.cs b/ICSharpCode.Decompiler/CSharp/Transforms/CombineQueryExpressions.cs index dea7a451b..91405aa6e 100644 --- a/ICSharpCode.Decompiler/CSharp/Transforms/CombineQueryExpressions.cs +++ b/ICSharpCode.Decompiler/CSharp/Transforms/CombineQueryExpressions.cs @@ -17,6 +17,7 @@ // DEALINGS IN THE SOFTWARE. using System; +using System.Collections.Generic; using System.Linq; using ICSharpCode.Decompiler.CSharp.Syntax; using ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching; @@ -32,7 +33,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms { if (!context.Settings.QueryExpressions) return; - CombineQueries(rootNode); + CombineQueries(rootNode, new Dictionary()); } static readonly InvocationExpression castPattern = new InvocationExpression { @@ -42,18 +43,18 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms TypeArguments = { new AnyNode("targetType") } }}; - void CombineQueries(AstNode node) + void CombineQueries(AstNode node, Dictionary letIdentifiers) { for (AstNode child = node.FirstChild; child != null; child = child.NextSibling) { - CombineQueries(child); + CombineQueries(child, letIdentifiers); } QueryExpression query = node as QueryExpression; if (query != null) { QueryFromClause fromClause = (QueryFromClause)query.Clauses.First(); QueryExpression innerQuery = fromClause.Expression as QueryExpression; if (innerQuery != null) { - if (TryRemoveTransparentIdentifier(query, fromClause, innerQuery)) { - RemoveTransparentIdentifierReferences(query); + if (TryRemoveTransparentIdentifier(query, fromClause, innerQuery, letIdentifiers)) { + RemoveTransparentIdentifierReferences(query, letIdentifiers); } else { QueryContinuationClause continuation = new QueryContinuationClause(); continuation.PrecedingQuery = innerQuery.Detach(); @@ -69,80 +70,65 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms } } } - + static readonly QuerySelectClause selectTransparentIdentifierPattern = new QuerySelectClause { - Expression = new Choice { - new AnonymousTypeCreateExpression { - Initializers = { - new NamedExpression { - Name = Pattern.AnyString, - Expression = new IdentifierExpression(Pattern.AnyString) - }.WithName("nae1"), - new NamedExpression { - Name = Pattern.AnyString, - Expression = new AnyNode("nae2Expr") - }.WithName("nae2") - } - }, - new AnonymousTypeCreateExpression { - Initializers = { - new NamedNode("identifier", new IdentifierExpression(Pattern.AnyString)), - new AnyNode("nae2Expr") - } + Expression = new AnonymousTypeCreateExpression { + Initializers = { + new Repeat( + new Choice { + new IdentifierExpression(Pattern.AnyString).WithName("expr"), // capture variable with same name + new NamedExpression { + Name = Pattern.AnyString, + Expression = new AnyNode() + }.WithName("expr") + } + ) { MinCount = 1 } } - }}; - + } + }; + bool IsTransparentIdentifier(string identifier) { return identifier.StartsWith("<>", StringComparison.Ordinal) && (identifier.Contains("TransparentIdentifier") || identifier.Contains("TranspIdent")); } - bool TryRemoveTransparentIdentifier(QueryExpression query, QueryFromClause fromClause, QueryExpression innerQuery) + bool TryRemoveTransparentIdentifier(QueryExpression query, QueryFromClause fromClause, QueryExpression innerQuery, Dictionary letClauses) { if (!IsTransparentIdentifier(fromClause.Identifier)) return false; - Match match = selectTransparentIdentifierPattern.Match(innerQuery.Clauses.Last()); + QuerySelectClause selectClause = innerQuery.Clauses.Last() as QuerySelectClause; + Match match = selectTransparentIdentifierPattern.Match(selectClause); if (!match.Success) return false; - QuerySelectClause selectClause = (QuerySelectClause)innerQuery.Clauses.Last(); - NamedExpression nae1 = match.Get("nae1").SingleOrDefault(); - NamedExpression nae2 = match.Get("nae2").SingleOrDefault(); - if (nae1 != null && nae1.Name != ((IdentifierExpression)nae1.Expression).Identifier) - return false; - Expression nae2Expr = match.Get("nae2Expr").Single(); - IdentifierExpression nae2IdentExpr = nae2Expr as IdentifierExpression; - if (nae2IdentExpr != null && (nae2 == null || nae2.Name == nae2IdentExpr.Identifier)) { - // from * in (from x in ... select new { x = x, y = y }) ... - // => - // from x in ... ... - fromClause.Remove(); - selectClause.Remove(); - // Move clauses from innerQuery to query - QueryClause insertionPos = null; - foreach (var clause in innerQuery.Clauses) { - query.Clauses.InsertAfter(insertionPos, insertionPos = clause.Detach()); - } - } else { - // from * in (from x in ... select new { x = x, y = expr }) ... - // => - // from x in ... let y = expr ... - fromClause.Remove(); - selectClause.Remove(); - // Move clauses from innerQuery to query - QueryClause insertionPos = null; - foreach (var clause in innerQuery.Clauses) { - query.Clauses.InsertAfter(insertionPos, insertionPos = clause.Detach()); + + // from * in (from x in ... select new { members of anonymous type }) ... + // => + // from x in ... { let x = ... } ... + fromClause.Remove(); + selectClause.Remove(); + // Move clauses from innerQuery to query + QueryClause insertionPos = null; + foreach (var clause in innerQuery.Clauses) { + query.Clauses.InsertAfter(insertionPos, insertionPos = clause.Detach()); + } + + foreach (var expr in match.Get("expr")) { + switch (expr) { + case IdentifierExpression identifier: + // nothing to add + continue; + case NamedExpression namedExpression: + if (namedExpression.Expression is IdentifierExpression identifierExpression && namedExpression.Name == identifierExpression.Identifier) { + letClauses[namedExpression.Name] = identifierExpression.Annotation(); + continue; + } + QueryLetClause letClause = new QueryLetClause { Identifier = namedExpression.Name, Expression = namedExpression.Expression.Detach() }; + var annotation = new LetIdentifierAnnotation(); + letClause.AddAnnotation(annotation); + letClauses[namedExpression.Name] = annotation; + query.Clauses.InsertAfter(insertionPos, letClause); + break; } - string ident; - if (nae2 != null) - ident = nae2.Name; - else if (nae2Expr is IdentifierExpression) - ident = ((IdentifierExpression)nae2Expr).Identifier; - else if (nae2Expr is MemberReferenceExpression) - ident = ((MemberReferenceExpression)nae2Expr).MemberName; - else - throw new InvalidOperationException("Could not infer name from initializer in AnonymousTypeCreateExpression"); - query.Clauses.InsertAfter(insertionPos, new QueryLetClause { Identifier = ident, Expression = nae2Expr.Detach() }); } return true; } @@ -150,10 +136,10 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms /// /// Removes all occurrences of transparent identifiers /// - void RemoveTransparentIdentifierReferences(AstNode node) + void RemoveTransparentIdentifierReferences(AstNode node, Dictionary letClauses) { foreach (AstNode child in node.Children) { - RemoveTransparentIdentifierReferences(child); + RemoveTransparentIdentifierReferences(child, letClauses); } MemberReferenceExpression mre = node as MemberReferenceExpression; if (mre != null) { @@ -162,11 +148,17 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms IdentifierExpression newIdent = new IdentifierExpression(mre.MemberName); mre.TypeArguments.MoveTo(newIdent.TypeArguments); newIdent.CopyAnnotationsFrom(mre); - newIdent.RemoveAnnotations(); // remove the reference to the property of the anonymous type + newIdent.RemoveAnnotations(); // remove the reference to the property of the anonymous type + if (letClauses.TryGetValue(mre.MemberName, out var annotation)) + newIdent.AddAnnotation(annotation); mre.ReplaceWith(newIdent); return; } } } } + + public class LetIdentifierAnnotation + { + } } diff --git a/ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs b/ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs index b7a603af4..6d0a8c3d9 100644 --- a/ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs +++ b/ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs @@ -187,10 +187,10 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms private static bool IsValidInStatementExpression(Expression expr) { switch (expr) { - case InvocationExpression ie: - case ObjectCreateExpression oce: - case AssignmentExpression ae: - case ErrorExpression ee: + case InvocationExpression _: + case ObjectCreateExpression _: + case AssignmentExpression _: + case ErrorExpression _: return true; case UnaryOperatorExpression uoe: switch (uoe.Operator) { @@ -249,12 +249,27 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms newPoint = scopeTracking[startIndex + 1].InsertionPoint; } else { newPoint = new InsertionPoint { level = nodeLevel, nextNode = identExpr }; + if (variable.HasInitialValue) { + // Uninitialized variables are logically initialized at the beginning of the functin + // Because it's possible that the variable has a loop-carried dependency, + // declare it outside of any loops. + while (startIndex >= 0) { + if (scopeTracking[startIndex].Scope.EntryPoint.IncomingEdgeCount > 1) { + // declare variable outside of loop + newPoint = scopeTracking[startIndex].InsertionPoint; + } else if (scopeTracking[startIndex].Scope.Parent is ILFunction) { + // stop at beginning of function + break; + } + startIndex--; + } + } } VariableToDeclare v; - if (variableDict.TryGetValue(rr.Variable, out v)) { + if (variableDict.TryGetValue(variable, out v)) { v.InsertionPoint = FindCommonParent(v.InsertionPoint, newPoint); } else { - v = new VariableToDeclare(rr.Variable, rr.Variable.HasInitialValue, + v = new VariableToDeclare(variable, variable.HasInitialValue, newPoint, identExpr, sourceOrder: variableDict.Count); variableDict.Add(rr.Variable, v); } @@ -271,7 +286,8 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms switch (kind) { case VariableKind.PinnedLocal: case VariableKind.Parameter: - case VariableKind.Exception: + case VariableKind.ExceptionLocal: + case VariableKind.ExceptionStackSlot: case VariableKind.UsingLocal: case VariableKind.ForeachLocal: return false; diff --git a/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceQueryExpressions.cs b/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceQueryExpressions.cs index 38e1c35a1..83896b873 100644 --- a/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceQueryExpressions.cs +++ b/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceQueryExpressions.cs @@ -40,7 +40,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms QueryFromClause fromClause = (QueryFromClause)query.Clauses.First(); if (IsDegenerateQuery(query)) { // introduce select for degenerate query - query.Clauses.Add(new QuerySelectClause { Expression = new IdentifierExpression(fromClause.Identifier) }); + query.Clauses.Add(new QuerySelectClause { Expression = new IdentifierExpression(fromClause.Identifier).CopyAnnotationsFrom(fromClause) }); } // See if the data source of this query is a degenerate query, // and combine the queries if possible. @@ -74,7 +74,10 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms QueryExpression query = DecompileQuery(node as InvocationExpression); if (query != null) node.ReplaceWith(query); - for (AstNode child = (query ?? node).FirstChild; child != null; child = child.NextSibling) { + AstNode next; + for (AstNode child = (query ?? node).FirstChild; child != null; child = next) { + // store referece to next child before transformation + next = child.NextSibling; DecompileQueries(child); } } @@ -91,12 +94,12 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms { if (invocation.Arguments.Count != 1) return null; - string parameterName; + ParameterDeclaration parameter; Expression body; - if (MatchSimpleLambda(invocation.Arguments.Single(), out parameterName, out body)) { + if (MatchSimpleLambda(invocation.Arguments.Single(), out parameter, out body)) { QueryExpression query = new QueryExpression(); - query.Clauses.Add(new QueryFromClause { Identifier = parameterName, Expression = mre.Target.Detach() }); - query.Clauses.Add(new QuerySelectClause { Expression = WrapExpressionInParenthesesIfNecessary(body.Detach(), parameterName) }); + query.Clauses.Add(MakeFromClause(parameter, mre.Target.Detach())); + query.Clauses.Add(new QuerySelectClause { Expression = WrapExpressionInParenthesesIfNecessary(body.Detach(), parameter.Name) }); return query; } return null; @@ -104,24 +107,24 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms case "GroupBy": { if (invocation.Arguments.Count == 2) { - string parameterName1, parameterName2; + ParameterDeclaration parameter1, parameter2; Expression keySelector, elementSelector; - if (MatchSimpleLambda(invocation.Arguments.ElementAt(0), out parameterName1, out keySelector) - && MatchSimpleLambda(invocation.Arguments.ElementAt(1), out parameterName2, out elementSelector) - && parameterName1 == parameterName2) + if (MatchSimpleLambda(invocation.Arguments.ElementAt(0), out parameter1, out keySelector) + && MatchSimpleLambda(invocation.Arguments.ElementAt(1), out parameter2, out elementSelector) + && parameter1.Name == parameter2.Name) { QueryExpression query = new QueryExpression(); - query.Clauses.Add(new QueryFromClause { Identifier = parameterName1, Expression = mre.Target.Detach() }); + query.Clauses.Add(MakeFromClause(parameter1, mre.Target.Detach())); query.Clauses.Add(new QueryGroupClause { Projection = elementSelector.Detach(), Key = keySelector.Detach() }); return query; } } else if (invocation.Arguments.Count == 1) { - string parameterName; + ParameterDeclaration parameter; Expression keySelector; - if (MatchSimpleLambda(invocation.Arguments.Single(), out parameterName, out keySelector)) { + if (MatchSimpleLambda(invocation.Arguments.Single(), out parameter, out keySelector)) { QueryExpression query = new QueryExpression(); - query.Clauses.Add(new QueryFromClause { Identifier = parameterName, Expression = mre.Target.Detach() }); - query.Clauses.Add(new QueryGroupClause { Projection = new IdentifierExpression(parameterName), Key = keySelector.Detach() }); + query.Clauses.Add(MakeFromClause(parameter, mre.Target.Detach())); + query.Clauses.Add(new QueryGroupClause { Projection = new IdentifierExpression(parameter.Name).CopyAnnotationsFrom(parameter), Key = keySelector.Detach() }); return query; } } @@ -131,9 +134,9 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms { if (invocation.Arguments.Count != 2) return null; - string parameterName; + ParameterDeclaration parameter; Expression collectionSelector; - if (!MatchSimpleLambda(invocation.Arguments.ElementAt(0), out parameterName, out collectionSelector)) + if (!MatchSimpleLambda(invocation.Arguments.ElementAt(0), out parameter, out collectionSelector)) return null; if (IsNullConditional(collectionSelector)) return null; @@ -141,11 +144,11 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms if (lambda != null && lambda.Parameters.Count == 2 && lambda.Body is Expression) { ParameterDeclaration p1 = lambda.Parameters.ElementAt(0); ParameterDeclaration p2 = lambda.Parameters.ElementAt(1); - if (p1.Name == parameterName) { + if (p1.Name == parameter.Name) { QueryExpression query = new QueryExpression(); - query.Clauses.Add(new QueryFromClause { Identifier = p1.Name, Expression = mre.Target.Detach() }); - query.Clauses.Add(new QueryFromClause { Identifier = p2.Name, Expression = collectionSelector.Detach() }); - query.Clauses.Add(new QuerySelectClause { Expression = WrapExpressionInParenthesesIfNecessary(((Expression)lambda.Body).Detach(), parameterName) }); + query.Clauses.Add(MakeFromClause(p1, mre.Target.Detach())); + query.Clauses.Add(MakeFromClause(p2, collectionSelector.Detach())); + query.Clauses.Add(new QuerySelectClause { Expression = WrapExpressionInParenthesesIfNecessary(((Expression)lambda.Body).Detach(), parameter.Name) }); return query; } } @@ -155,11 +158,11 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms { if (invocation.Arguments.Count != 1) return null; - string parameterName; + ParameterDeclaration parameter; Expression body; - if (MatchSimpleLambda(invocation.Arguments.Single(), out parameterName, out body)) { + if (MatchSimpleLambda(invocation.Arguments.Single(), out parameter, out body)) { QueryExpression query = new QueryExpression(); - query.Clauses.Add(new QueryFromClause { Identifier = parameterName, Expression = mre.Target.Detach() }); + query.Clauses.Add(MakeFromClause(parameter, mre.Target.Detach())); query.Clauses.Add(new QueryWhereClause { Condition = body.Detach() }); return query; } @@ -172,10 +175,10 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms { if (invocation.Arguments.Count != 1) return null; - string parameterName; + ParameterDeclaration parameter; Expression orderExpression; - if (MatchSimpleLambda(invocation.Arguments.Single(), out parameterName, out orderExpression)) { - if (ValidateThenByChain(invocation, parameterName)) { + if (MatchSimpleLambda(invocation.Arguments.Single(), out parameter, out orderExpression)) { + if (ValidateThenByChain(invocation, parameter.Name)) { QueryOrderClause orderClause = new QueryOrderClause(); InvocationExpression tmp = invocation; while (mre.MemberName == "ThenBy" || mre.MemberName == "ThenByDescending") { @@ -188,7 +191,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms tmp = (InvocationExpression)mre.Target; mre = (MemberReferenceExpression)tmp.Target; - MatchSimpleLambda(tmp.Arguments.Single(), out parameterName, out orderExpression); + MatchSimpleLambda(tmp.Arguments.Single(), out parameter, out orderExpression); } // insert new ordering at beginning orderClause.Orderings.InsertAfter( @@ -198,7 +201,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms }); QueryExpression query = new QueryExpression(); - query.Clauses.Add(new QueryFromClause { Identifier = parameterName, Expression = mre.Target.Detach() }); + query.Clauses.Add(MakeFromClause(parameter, mre.Target.Detach())); query.Clauses.Add(orderClause); return query; } @@ -214,21 +217,21 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms Expression source2 = invocation.Arguments.ElementAt(0); if (IsNullConditional(source2)) return null; - string elementName1, elementName2; + ParameterDeclaration element1, element2; Expression key1, key2; - if (!MatchSimpleLambda(invocation.Arguments.ElementAt(1), out elementName1, out key1)) + if (!MatchSimpleLambda(invocation.Arguments.ElementAt(1), out element1, out key1)) return null; - if (!MatchSimpleLambda(invocation.Arguments.ElementAt(2), out elementName2, out key2)) + if (!MatchSimpleLambda(invocation.Arguments.ElementAt(2), out element2, out key2)) return null; LambdaExpression lambda = invocation.Arguments.ElementAt(3) as LambdaExpression; if (lambda != null && lambda.Parameters.Count == 2 && lambda.Body is Expression) { ParameterDeclaration p1 = lambda.Parameters.ElementAt(0); ParameterDeclaration p2 = lambda.Parameters.ElementAt(1); - if (p1.Name == elementName1 && (p2.Name == elementName2 || mre.MemberName == "GroupJoin")) { + if (p1.Name == element1.Name && (p2.Name == element2.Name || mre.MemberName == "GroupJoin")) { QueryExpression query = new QueryExpression(); - query.Clauses.Add(new QueryFromClause { Identifier = elementName1, Expression = source1.Detach() }); + query.Clauses.Add(MakeFromClause(element1, source1.Detach())); QueryJoinClause joinClause = new QueryJoinClause(); - joinClause.JoinIdentifier = elementName2; // join elementName2 + joinClause.JoinIdentifier = element2.Name; // join elementName2 joinClause.InExpression = source2.Detach(); // in source2 joinClause.OnExpression = key1.Detach(); // on key1 joinClause.EqualsExpression = key2.Detach(); // equals key2 @@ -247,6 +250,35 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms } } + QueryFromClause MakeFromClause(ParameterDeclaration parameter, Expression body) + { + QueryFromClause fromClause = new QueryFromClause { + Identifier = parameter.Name, + Expression = body + }; + fromClause.CopyAnnotationsFrom(parameter); + return fromClause; + } + + class ApplyAnnotationVisitor : DepthFirstAstVisitor + { + private LetIdentifierAnnotation annotation; + private string identifier; + + public ApplyAnnotationVisitor(LetIdentifierAnnotation annotation, string identifier) + { + this.annotation = annotation; + this.identifier = identifier; + } + + public override AstNode VisitIdentifier(Identifier identifier) + { + if (identifier.Name == this.identifier) + identifier.AddAnnotation(annotation); + return identifier; + } + } + bool IsNullConditional(Expression target) { return target is UnaryOperatorExpression uoe && uoe.Operator == UnaryOperatorType.NullConditional; @@ -275,11 +307,11 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms MemberReferenceExpression mre = invocation.Target as MemberReferenceExpression; if (mre == null) return false; - string parameterName; + ParameterDeclaration parameter; Expression body; - if (!MatchSimpleLambda(invocation.Arguments.Single(), out parameterName, out body)) + if (!MatchSimpleLambda(invocation.Arguments.Single(), out parameter, out body)) return false; - if (parameterName != expectedParameterName) + if (parameter.Name != expectedParameterName) return false; if (mre.MemberName == "OrderBy" || mre.MemberName == "OrderByDescending") @@ -291,7 +323,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms } /// Matches simple lambdas of the form "a => b" - bool MatchSimpleLambda(Expression expr, out string parameterName, out Expression body) + bool MatchSimpleLambda(Expression expr, out ParameterDeclaration parameter, out Expression body) { // HACK : remove workaround after all unnecessary casts are eliminated. LambdaExpression lambda; @@ -302,12 +334,12 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms if (lambda != null && lambda.Parameters.Count == 1 && lambda.Body is Expression) { ParameterDeclaration p = lambda.Parameters.Single(); if (p.ParameterModifier == ParameterModifier.None) { - parameterName = p.Name; + parameter = p; body = (Expression)lambda.Body; return true; } } - parameterName = null; + parameter = null; body = null; return false; } diff --git a/ICSharpCode.Decompiler/DebugInfo/ScopesGenerator.cs b/ICSharpCode.Decompiler/DebugInfo/ScopesGenerator.cs index 136ee326a..9b209d946 100644 --- a/ICSharpCode.Decompiler/DebugInfo/ScopesGenerator.cs +++ b/ICSharpCode.Decompiler/DebugInfo/ScopesGenerator.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Reflection.Metadata; using System.Reflection.Metadata.Ecma335; @@ -33,7 +34,7 @@ namespace ICSharpCode.Decompiler.DebugInfo { class ScopesGenerator : DepthFirstAstVisitor { - static readonly KeyComparer ILVariableKeyComparer = new KeyComparer(l => l.Index, Comparer.Default, EqualityComparer.Default); + static readonly KeyComparer ILVariableKeyComparer = new KeyComparer(l => l.Index.Value, Comparer.Default, EqualityComparer.Default); IDecompilerTypeSystem typeSystem; ImportScopeInfo currentImportScope; @@ -59,7 +60,7 @@ namespace ICSharpCode.Decompiler.DebugInfo var firstLocalVariable = MetadataTokens.LocalVariableHandle(nextRow); foreach (var local in localScope.Locals.OrderBy(l => l.Index)) { - metadata.AddLocalVariable(LocalVariableAttributes.None, local.Index, metadata.GetOrAddString(local.Name)); + metadata.AddLocalVariable(LocalVariableAttributes.None, local.Index.Value, metadata.GetOrAddString(local.Name)); } metadata.AddLocalScope(localScope.Method, localScope.Import.Handle, firstLocalVariable, @@ -191,14 +192,15 @@ namespace ICSharpCode.Decompiler.DebugInfo new TypeSystem.GenericContext(function.Method)); foreach (var v in function.Variables) { + if (v.Index == null) + continue; switch (v.Kind) { case VariableKind.Local: case VariableKind.PinnedLocal: case VariableKind.UsingLocal: case VariableKind.ForeachLocal: - if (v.Index < types.Length && v.Type.Equals(types[v.Index])) { - localVariables.Add(v); - } + Debug.Assert(v.Index < types.Length && v.Type.Equals(types[v.Index.Value])); + localVariables.Add(v); break; default: continue; diff --git a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj index 33c7fb57d..dc3c1c204 100644 --- a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj +++ b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj @@ -3,13 +3,12 @@ - netstandard2.0 - netstandard2.0;net46;net45 + netstandard2.0 IL decompiler engine ic#code ILSpy - Copyright 2011-2018 AlphaSierraPapa for the SharpDevelop Team + Copyright 2011-2019 AlphaSierraPapa for the SharpDevelop Team en-US False False @@ -74,7 +73,7 @@ - + @@ -267,6 +266,7 @@ + diff --git a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec.template b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec.template index 4e7bd6757..7f01f6e4a 100644 --- a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec.template +++ b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.nuspec.template @@ -22,12 +22,6 @@ - - - - - - diff --git a/ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs b/ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs index 2ee23fa63..53bb9b97b 100644 --- a/ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs +++ b/ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs @@ -565,7 +565,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow } awaitBlocks.Add(block, (awaiterVar, awaiterField)); if (awaiterVar.Index < smallestAwaiterVarIndex) { - smallestAwaiterVarIndex = awaiterVar.Index; + smallestAwaiterVarIndex = awaiterVar.Index.Value; } } } diff --git a/ICSharpCode.Decompiler/IL/ILReader.cs b/ICSharpCode.Decompiler/IL/ILReader.cs index ec6a8a0a6..aea71a8c0 100644 --- a/ICSharpCode.Decompiler/IL/ILReader.cs +++ b/ICSharpCode.Decompiler/IL/ILReader.cs @@ -225,11 +225,6 @@ namespace ICSharpCode.Decompiler.IL ILVariable CreateILVariable(int index, IType parameterType, string name) { Debug.Assert(!parameterType.IsUnbound()); - if (parameterType.IsUnbound()) { - // parameter types should not be unbound, the only known cause for these is a Cecil bug: - Debug.Assert(index < 0); // cecil bug occurs only for "this" - parameterType = new ParameterizedType(parameterType.GetDefinition(), parameterType.TypeArguments); - } ITypeDefinition def = parameterType.GetDefinition(); if (def != null && index < 0 && def.IsReferenceType == false) { parameterType = new ByReferenceType(parameterType); @@ -352,14 +347,14 @@ namespace ICSharpCode.Decompiler.IL ImmutableStack ehStack = null; if (eh.Kind == ExceptionRegionKind.Catch) { var catchType = module.ResolveType(eh.CatchType, genericContext); - var v = new ILVariable(VariableKind.Exception, catchType, eh.HandlerOffset) { + var v = new ILVariable(VariableKind.ExceptionStackSlot, catchType, eh.HandlerOffset) { Name = "E_" + eh.HandlerOffset, HasGeneratedName = true }; variableByExceptionHandler.Add(eh, v); ehStack = ImmutableStack.Create(v); } else if (eh.Kind == ExceptionRegionKind.Filter) { - var v = new ILVariable(VariableKind.Exception, compilation.FindType(KnownTypeCode.Object), eh.HandlerOffset) { + var v = new ILVariable(VariableKind.ExceptionStackSlot, compilation.FindType(KnownTypeCode.Object), eh.HandlerOffset) { Name = "E_" + eh.HandlerOffset, HasGeneratedName = true }; @@ -1060,7 +1055,7 @@ namespace ICSharpCode.Decompiler.IL { Debug.Assert(inst.ResultType != StackType.Void); IType type = compilation.FindType(inst.ResultType.ToKnownTypeCode()); - var v = new ILVariable(VariableKind.StackSlot, type, inst.ResultType, inst.ILRange.Start); + var v = new ILVariable(VariableKind.StackSlot, type, inst.ResultType); v.HasGeneratedName = true; currentStack = currentStack.Push(v); return new StLoc(v, inst); diff --git a/ICSharpCode.Decompiler/IL/ILVariable.cs b/ICSharpCode.Decompiler/IL/ILVariable.cs index 64d0c6611..0c3c7eaeb 100644 --- a/ICSharpCode.Decompiler/IL/ILVariable.cs +++ b/ICSharpCode.Decompiler/IL/ILVariable.cs @@ -51,9 +51,13 @@ namespace ICSharpCode.Decompiler.IL /// Parameter, /// - /// Variable created for exception handler + /// Variable created for exception handler. /// - Exception, + ExceptionStackSlot, + /// + /// Local variable used in a catch block. + /// + ExceptionLocal, /// /// Variable created from stack slot. /// @@ -96,9 +100,40 @@ namespace ICSharpCode.Decompiler.IL /// /// The index of the local variable or parameter (depending on Kind) + /// + /// For VariableKinds with "Local" in the name: + /// * if non-null, the Index refers to the LocalVariableSignature. + /// * index may be null for variables that used to be fields (captured by lambda/async) + /// For Parameters, the Index refers to the method's list of parameters. + /// The special "this" parameter has index -1. + /// For ExceptionStackSlot, the index is the IL offset of the exception handler. + /// For other kinds, the index has no meaning, and is usually null. /// - public readonly int Index; + public readonly int? Index; + [Conditional("DEBUG")] + internal void CheckInvariant() + { + switch (kind) { + case VariableKind.Local: + case VariableKind.ForeachLocal: + case VariableKind.PinnedLocal: + case VariableKind.UsingLocal: + case VariableKind.ExceptionLocal: + // in range of LocalVariableSignature + Debug.Assert(Index == null || Index >= 0); + break; + case VariableKind.Parameter: + // -1 for the "this" parameter + Debug.Assert(Index >= -1); + Debug.Assert(Function == null || Index < Function.Parameters.Count); + break; + case VariableKind.ExceptionStackSlot: + Debug.Assert(Index >= 0); + break; + } + } + public string Name { get; set; } public bool HasGeneratedName { get; set; } @@ -268,7 +303,7 @@ namespace ICSharpCode.Decompiler.IL /// public IField StateMachineField; - public ILVariable(VariableKind kind, IType type, int index) + public ILVariable(VariableKind kind, IType type, int? index = null) { if (type == null) throw new ArgumentNullException(nameof(type)); @@ -278,9 +313,10 @@ namespace ICSharpCode.Decompiler.IL this.Index = index; if (kind == VariableKind.Parameter) this.HasInitialValue = true; + CheckInvariant(); } - public ILVariable(VariableKind kind, IType type, StackType stackType, int index) + public ILVariable(VariableKind kind, IType type, StackType stackType, int? index = null) { if (type == null) throw new ArgumentNullException(nameof(type)); @@ -290,8 +326,9 @@ namespace ICSharpCode.Decompiler.IL this.Index = index; if (kind == VariableKind.Parameter) this.HasInitialValue = true; + CheckInvariant(); } - + public override string ToString() { return Name; @@ -309,8 +346,11 @@ namespace ICSharpCode.Decompiler.IL case VariableKind.Parameter: output.Write("param "); break; - case VariableKind.Exception: - output.Write("exception "); + case VariableKind.ExceptionLocal: + output.Write("exception local "); + break; + case VariableKind.ExceptionStackSlot: + output.Write("exception stack "); break; case VariableKind.StackSlot: output.Write("stack "); @@ -403,7 +443,7 @@ namespace ICSharpCode.Decompiler.IL return false; if (x.Kind == VariableKind.StackSlot || y.Kind == VariableKind.StackSlot) return false; - return x.Function == y.Function && x.Kind == y.Kind && x.Index == y.Index; + return x.Index != null && x.Function == y.Function && x.Kind == y.Kind && x.Index == y.Index; } public int GetHashCode(ILVariable obj) diff --git a/ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs b/ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs index 559aaa7e4..9da35d02f 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs @@ -98,6 +98,7 @@ namespace ICSharpCode.Decompiler.IL for (int i = 0; i < Variables.Count; i++) { Debug.Assert(Variables[i].Function == this); Debug.Assert(Variables[i].IndexInFunction == i); + Variables[i].CheckInvariant(); } base.CheckInvariant(phase); } @@ -213,32 +214,13 @@ namespace ICSharpCode.Decompiler.IL } } + int helperVariableCount; + public ILVariable RegisterVariable(VariableKind kind, IType type, string name = null) { - int index = Variables.Where(v => v.Kind == kind).MaxOrDefault(v => v.Index, -1) + 1; - var variable = new ILVariable(kind, type, index); + var variable = new ILVariable(kind, type); if (string.IsNullOrWhiteSpace(name)) { - switch (kind) { - case VariableKind.Local: - case VariableKind.ForeachLocal: - name = "V_"; - break; - case VariableKind.Parameter: - name = "P_"; - break; - case VariableKind.Exception: - name = "E_"; - break; - case VariableKind.StackSlot: - name = "S_"; - break; - case VariableKind.InitializerTarget: - name = "I_"; - break; - default: - throw new ArgumentOutOfRangeException(nameof(kind)); - } - name += index; + name = "I_" + (helperVariableCount++); variable.HasGeneratedName = true; } variable.Name = name; diff --git a/ICSharpCode.Decompiler/IL/Transforms/CombineExitsTransform.cs b/ICSharpCode.Decompiler/IL/Transforms/CombineExitsTransform.cs new file mode 100644 index 000000000..8da6ceb66 --- /dev/null +++ b/ICSharpCode.Decompiler/IL/Transforms/CombineExitsTransform.cs @@ -0,0 +1,51 @@ +// Copyright (c) 2019 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. + +namespace ICSharpCode.Decompiler.IL.Transforms +{ + class CombineExitsTransform : IILTransform + { + public void Run(ILFunction function, ILTransformContext context) + { + if (!(function.Body is BlockContainer container && container.Blocks.Count == 1)) + return; + var block = container.EntryPoint; + if (!(block.Instructions.SecondToLastOrDefault() is IfInstruction ifInst && block.Instructions.LastOrDefault() is Leave leaveElse)) + return; + if (!ifInst.FalseInst.MatchNop()) + return; + if (!(Block.Unwrap(ifInst.TrueInst) is Leave leave)) + return; + if (!(leave.IsLeavingFunction && leaveElse.IsLeavingFunction)) + return; + if (leave.Value.MatchNop() || leaveElse.Value.MatchNop()) + return; + // if (cond) { + // leave (value) + // } + // leave (elseValue) + // => + // leave (if (cond) value else elseValue) + IfInstruction value = new IfInstruction(ifInst.Condition, leave.Value, leaveElse.Value) { ILRange = ifInst.ILRange }; + Leave combinedLeave = new Leave(leave.TargetContainer, value) { ILRange = leaveElse.ILRange }; + combinedLeave.AddILRange(leave.ILRange); + ifInst.ReplaceWith(combinedLeave); + block.Instructions.RemoveAt(combinedLeave.ChildIndex + 1); + } + } +} diff --git a/ICSharpCode.Decompiler/IL/Transforms/CopyPropagation.cs b/ICSharpCode.Decompiler/IL/Transforms/CopyPropagation.cs index 9b17c41eb..b2e7a984b 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/CopyPropagation.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/CopyPropagation.cs @@ -89,7 +89,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms // note: the initialization by the caller is the first store -> StoreCount must be 1 return v.IsSingleDefinition; case VariableKind.StackSlot: - case VariableKind.Exception: // Exception variables are normally generated as well. + case VariableKind.ExceptionStackSlot: // Variables are be copied only if both they and the target copy variable are generated, // and if the variable has only a single assignment return v.IsSingleDefinition && target.Kind == VariableKind.StackSlot; @@ -110,8 +110,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms for (int j = 0; j < uninlinedArgs.Length; j++) { var arg = copiedExpr.Children[j]; var type = context.TypeSystem.FindType(arg.ResultType.ToKnownTypeCode()); - uninlinedArgs[j] = new ILVariable(VariableKind.StackSlot, type, arg.ResultType, arg.ILRange.Start) { - Name = "C_" + arg.ILRange.Start + uninlinedArgs[j] = new ILVariable(VariableKind.StackSlot, type, arg.ResultType) { + Name = "C_" + arg.ILRange.Start, + HasGeneratedName = true, }; block.Instructions.Insert(i++, new StLoc(uninlinedArgs[j], arg)); } diff --git a/ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs b/ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs index 4d8606751..7a04540da 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs @@ -105,13 +105,24 @@ namespace ICSharpCode.Decompiler.IL.Transforms static bool IsAnonymousMethod(ITypeDefinition decompiledTypeDefinition, IMethod method) { - if (method == null || !(method.HasGeneratedName() || method.Name.Contains("$"))) + if (method == null || !(method.HasGeneratedName() || method.Name.Contains("$") || ContainsAnonymousType(method))) return false; if (!(method.IsCompilerGeneratedOrIsInCompilerGeneratedClass() || IsPotentialClosure(decompiledTypeDefinition, method.DeclaringTypeDefinition))) return false; return true; } - + + static bool ContainsAnonymousType(IMethod method) + { + if (method.ReturnType.ContainsAnonymousType()) + return true; + foreach (var p in method.Parameters) { + if (p.Type.ContainsAnonymousType()) + return true; + } + return false; + } + static bool IsPotentialClosure(ITypeDefinition decompiledTypeDefinition, ITypeDefinition potentialDisplayClass) { if (potentialDisplayClass == null || !potentialDisplayClass.IsCompilerGeneratedOrIsInCompilerGeneratedClass()) @@ -178,7 +189,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms } var nestedContext = new ILTransformContext(context, function); - function.RunTransforms(CSharpDecompiler.GetILTransforms().TakeWhile(t => !(t is DelegateConstruction)), nestedContext); + function.RunTransforms(CSharpDecompiler.GetILTransforms().TakeWhile(t => !(t is DelegateConstruction)).Concat(GetTransforms()), nestedContext); function.AcceptVisitor(new ReplaceDelegateTargetVisitor(target, function.Variables.SingleOrDefault(v => v.Index == -1 && v.Kind == VariableKind.Parameter))); // handle nested lambdas ((IILTransform)new DelegateConstruction()).Run(function, nestedContext); @@ -186,7 +197,12 @@ namespace ICSharpCode.Decompiler.IL.Transforms function.AddILRange(value.Arguments[1].ILRange); return function; } - + + private IEnumerable GetTransforms() + { + yield return new CombineExitsTransform(); + } + /// /// Replaces loads of 'this' with the target expression. /// Async delegates use: ldobj(ldloca this). diff --git a/ICSharpCode.Decompiler/IL/Transforms/DetectCatchWhenConditionBlocks.cs b/ICSharpCode.Decompiler/IL/Transforms/DetectCatchWhenConditionBlocks.cs index 872d0acd7..0fdbde147 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/DetectCatchWhenConditionBlocks.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/DetectCatchWhenConditionBlocks.cs @@ -27,7 +27,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms public void Run(ILFunction function, ILTransformContext context) { foreach (var catchBlock in function.Descendants.OfType()) { - if (catchBlock.Filter is BlockContainer container && MatchCatchWhenEntryPoint(container, container.EntryPoint, out var exceptionType, out var exceptionSlot, out var whenConditionBlock)) { + if (catchBlock.Filter is BlockContainer container && MatchCatchWhenEntryPoint(catchBlock.Variable, container, container.EntryPoint, out var exceptionType, out var exceptionSlot, out var whenConditionBlock)) { // set exceptionType catchBlock.Variable.Type = exceptionType; // Block entryPoint (incoming: 1) { @@ -67,7 +67,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms /// br falseBlock /// } /// - bool MatchCatchWhenEntryPoint(BlockContainer container, Block entryPoint, out IType exceptionType, out ILInstruction exceptionSlot, out Block whenConditionBlock) + bool MatchCatchWhenEntryPoint(ILVariable exceptionVar, BlockContainer container, Block entryPoint, out IType exceptionType, out ILInstruction exceptionSlot, out Block whenConditionBlock) { exceptionType = null; exceptionSlot = null; @@ -81,7 +81,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms if (!entryPoint.Instructions[0].MatchStLoc(out var temp, out var isinst) || temp.Kind != VariableKind.StackSlot || !isinst.MatchIsInst(out exceptionSlot, out exceptionType)) return false; - if (!exceptionSlot.MatchLdLoc(out var exceptionVar) || exceptionVar.Kind != VariableKind.Exception) + if (!exceptionSlot.MatchLdLoc(exceptionVar)) return false; if (!entryPoint.Instructions[1].MatchIfInstruction(out var condition, out var branch)) return false; @@ -103,7 +103,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms return false; if (!left.MatchIsInst(out exceptionSlot, out exceptionType)) return false; - if (!exceptionSlot.MatchLdLoc(out var exceptionVar) || exceptionVar.Kind != VariableKind.Exception) + if (!exceptionSlot.MatchLdLoc(exceptionVar)) return false; if (right.MatchLdNull()) { return branch.MatchBranch(out whenConditionBlock); diff --git a/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs b/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs index 56d604bf3..ea3f59466 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs @@ -613,7 +613,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms if (!exceptionSlotLoad.MatchLdLoc(handler.Variable) || !handler.Variable.IsSingleDefinition || handler.Variable.LoadCount != 1) return; handler.Variable = exceptionVar; - exceptionVar.Kind = VariableKind.Exception; + exceptionVar.Kind = VariableKind.ExceptionLocal; entryPoint.Instructions.RemoveAt(0); } diff --git a/ICSharpCode.Decompiler/IL/Transforms/SplitVariables.cs b/ICSharpCode.Decompiler/IL/Transforms/SplitVariables.cs index e2ecc193b..4dcf0720a 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/SplitVariables.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/SplitVariables.cs @@ -47,7 +47,6 @@ namespace ICSharpCode.Decompiler.IL.Transforms { switch (v.Kind) { case VariableKind.Local: - case VariableKind.Exception: foreach (var ldloca in v.AddressInstructions) { if (DetermineAddressUse(ldloca, ldloca.Variable) == AddressUse.Unknown) { // If we don't understand how the address is being used, diff --git a/ICSharpCode.Decompiler/Metadata/AssemblyReferences.cs b/ICSharpCode.Decompiler/Metadata/AssemblyReferences.cs index 70631c246..2fd984596 100644 --- a/ICSharpCode.Decompiler/Metadata/AssemblyReferences.cs +++ b/ICSharpCode.Decompiler/Metadata/AssemblyReferences.cs @@ -156,6 +156,11 @@ namespace ICSharpCode.Decompiler.Metadata return name; } + + public override string ToString() + { + return FullName; + } } public class AssemblyReference : IAssemblyReference diff --git a/ICSharpCode.Decompiler/Output/TextTokenWriter.cs b/ICSharpCode.Decompiler/Output/TextTokenWriter.cs index bd6bd9628..2f0a3d87b 100644 --- a/ICSharpCode.Decompiler/Output/TextTokenWriter.cs +++ b/ICSharpCode.Decompiler/Output/TextTokenWriter.cs @@ -63,34 +63,35 @@ namespace ICSharpCode.Decompiler } var definition = GetCurrentDefinition(); + string name = TextWriterTokenWriter.EscapeIdentifier(identifier.Name); switch (definition) { case IType t: - output.WriteReference(t, identifier.Name, true); + output.WriteReference(t, name, true); return; case IMember m: - output.WriteReference(m, identifier.Name, true); + output.WriteReference(m, name, true); return; } var member = GetCurrentMemberReference(); switch (member) { case IType t: - output.WriteReference(t, identifier.Name, false); + output.WriteReference(t, name, false); return; case IMember m: - output.WriteReference(m, identifier.Name, false); + output.WriteReference(m, name, false); return; } var localDefinition = GetCurrentLocalDefinition(); if (localDefinition != null) { - output.WriteLocalReference(identifier.Name, localDefinition, isDefinition: true); + output.WriteLocalReference(name, localDefinition, isDefinition: true); return; } var localRef = GetCurrentLocalReference(); if (localRef != null) { - output.WriteLocalReference(identifier.Name, localRef); + output.WriteLocalReference(name, localRef); return; } @@ -99,7 +100,7 @@ namespace ICSharpCode.Decompiler firstUsingDeclaration = false; } - output.Write(identifier.Name); + output.Write(name); } ISymbol GetCurrentMemberReference() @@ -140,6 +141,10 @@ namespace ICSharpCode.Decompiler if (variable != null) return variable; + var letClauseVariable = node.Annotation(); + if (letClauseVariable != null) + return letClauseVariable; + var gotoStatement = node as GotoStatement; if (gotoStatement != null) { @@ -163,6 +168,12 @@ namespace ICSharpCode.Decompiler return variable; } + if (node is QueryLetClause) { + var variable = node.Annotation(); + if (variable != null) + return variable; + } + var label = node as LabelStatement; if (label != null) { var method = nodeStack.Select(nd => nd.GetSymbol() as IMethod).FirstOrDefault(mr => mr != null); diff --git a/ILSpy.AddIn/ILSpy.AddIn.csproj b/ILSpy.AddIn/ILSpy.AddIn.csproj index 8b1df1687..fe169585b 100644 --- a/ILSpy.AddIn/ILSpy.AddIn.csproj +++ b/ILSpy.AddIn/ILSpy.AddIn.csproj @@ -7,7 +7,7 @@ - net46 + net462 ICSharpCode.ILSpy.AddIn IC#Code @@ -56,7 +56,7 @@ - + @@ -111,7 +111,7 @@ ..\ILSpy\bin\$(Configuration)\$(TargetFramework)\ - + @@ -138,7 +138,7 @@ - + @@ -183,12 +183,4 @@ - - - - - - - - \ No newline at end of file diff --git a/ILSpy.BamlDecompiler.Tests/Cases/AttachedEvent.xaml b/ILSpy.BamlDecompiler.Tests/Cases/AttachedEvent.xaml index 866abc9b6..4f45dfe48 100644 --- a/ILSpy.BamlDecompiler.Tests/Cases/AttachedEvent.xaml +++ b/ILSpy.BamlDecompiler.Tests/Cases/AttachedEvent.xaml @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/ILSpy.BamlDecompiler.Tests/Cases/AvalonDockBrushes.xaml b/ILSpy.BamlDecompiler.Tests/Cases/AvalonDockBrushes.xaml index cc7e517c9..b934fe7ca 100644 --- a/ILSpy.BamlDecompiler.Tests/Cases/AvalonDockBrushes.xaml +++ b/ILSpy.BamlDecompiler.Tests/Cases/AvalonDockBrushes.xaml @@ -1,23 +1,23 @@  - + - + - + - + - + - + - + @@ -29,25 +29,25 @@ - - + + - + - - - - - - + + + + + + - - + + - + \ No newline at end of file diff --git a/ILSpy.BamlDecompiler.Tests/Cases/AvalonDockCommon.xaml b/ILSpy.BamlDecompiler.Tests/Cases/AvalonDockCommon.xaml index bc3511614..bcb18aed2 100644 --- a/ILSpy.BamlDecompiler.Tests/Cases/AvalonDockCommon.xaml +++ b/ILSpy.BamlDecompiler.Tests/Cases/AvalonDockCommon.xaml @@ -2,7 +2,7 @@ - + @@ -10,24 +10,24 @@ - +