diff --git a/.github/workflows/build-frontends.yml b/.github/workflows/build-frontends.yml index 5f437b3d1f..67d3bee5b8 100644 --- a/.github/workflows/build-frontends.yml +++ b/.github/workflows/build-frontends.yml @@ -14,10 +14,10 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Setup .NET - uses: actions/setup-dotnet@v3 + - uses: actions/setup-dotnet@v4 with: - dotnet-version: 6.0.x + dotnet-version: '8.0.x' + dotnet-quality: 'ga' - name: Install dependencies run: dotnet restore ILSpy.XPlat.slnf diff --git a/.github/workflows/build-ilspy.yml b/.github/workflows/build-ilspy.yml index acc6c810cf..d2c9b6ab0f 100644 --- a/.github/workflows/build-ilspy.yml +++ b/.github/workflows/build-ilspy.yml @@ -26,6 +26,11 @@ jobs: submodules: true fetch-depth: 0 + - uses: actions/setup-dotnet@v4 + with: + dotnet-version: '8.0.x' + dotnet-quality: 'ga' + - name: Add msbuild to PATH uses: microsoft/setup-msbuild@v1.3 @@ -48,9 +53,9 @@ jobs: - name: Execute unit tests run: dotnet test --logger "junit;LogFileName=${{ matrix.configuration }}.xml" --results-directory test-results $env:Tests1 $env:Tests2 $env:Tests3 env: - Tests1: ICSharpCode.Decompiler.Tests\bin\${{ matrix.configuration }}\net6.0-windows\win-x64\ICSharpCode.Decompiler.Tests.dll - Tests2: ILSpy.Tests\bin\${{ matrix.configuration }}\net6.0-windows\ILSpy.Tests.dll - Tests3: ILSpy.BamlDecompiler.Tests\bin\${{ matrix.configuration }}\net6.0-windows\win-x64\ILSpy.BamlDecompiler.Tests.dll + Tests1: ICSharpCode.Decompiler.Tests\bin\${{ matrix.configuration }}\net8.0-windows\win-x64\ICSharpCode.Decompiler.Tests.dll + Tests2: ILSpy.Tests\bin\${{ matrix.configuration }}\net8.0-windows\ILSpy.Tests.dll + Tests3: ILSpy.BamlDecompiler.Tests\bin\${{ matrix.configuration }}\net8.0-windows\win-x64\ILSpy.BamlDecompiler.Tests.dll - name: Upload Test Logs uses: actions/upload-artifact@v3 @@ -76,7 +81,7 @@ jobs: git diff --exit-code - name: Zip ILSpy (framework-dependent) - run: 7z a -tzip $env:StagingDirectory\ILSpy_binaries.zip .\ILSpy\bin\${{ matrix.configuration }}\net6.0-windows\*.dll .\ILSpy\bin\${{ matrix.configuration }}\net6.0-windows\*.exe .\ILSpy\bin\${{ matrix.configuration }}\net6.0-windows\*.config .\ILSpy\bin\${{ matrix.configuration }}\net6.0-windows\*.json .\ILSpy\bin\${{ matrix.configuration }}\net6.0-windows\*\ILSpy.resources.dll .\ILSpy\bin\${{ matrix.configuration }}\net6.0-windows\*\ILSpy.ReadyToRun.Plugin.resources.dll + run: 7z a -tzip $env:StagingDirectory\ILSpy_binaries.zip .\ILSpy\bin\${{ matrix.configuration }}\net8.0-windows\*.dll .\ILSpy\bin\${{ matrix.configuration }}\net8.0-windows\*.exe .\ILSpy\bin\${{ matrix.configuration }}\net8.0-windows\*.config .\ILSpy\bin\${{ matrix.configuration }}\net8.0-windows\*.json .\ILSpy\bin\${{ matrix.configuration }}\net8.0-windows\*\ILSpy.resources.dll .\ILSpy\bin\${{ matrix.configuration }}\net8.0-windows\*\ILSpy.ReadyToRun.Plugin.resources.dll - name: Publish x64/arm64 framework-dependent/self-contained shell: pwsh @@ -84,11 +89,11 @@ jobs: - name: Zip ILSpy Release (x64 self-contained) if: matrix.configuration == 'release' - run: 7z a -tzip $env:StagingDirectory\ILSpy_selfcontained_x64.zip .\ILSpy\bin\Release\net6.0-windows\win-x64\publish\selfcontained\* + run: 7z a -tzip $env:StagingDirectory\ILSpy_selfcontained_x64.zip .\ILSpy\bin\Release\net8.0-windows\win-x64\publish\selfcontained\* - name: Zip ILSpy Release (arm64 framework-dependent) if: matrix.configuration == 'release' - run: 7z a -tzip $env:StagingDirectory\ILSpy_binaries_arm64.zip .\ILSpy\bin\Release\net6.0-windows\win-arm64\publish\fwdependent\* + run: 7z a -tzip $env:StagingDirectory\ILSpy_binaries_arm64.zip .\ILSpy\bin\Release\net8.0-windows\win-arm64\publish\fwdependent\* - name: Build Installer (x64 and arm64, framework-dependent) if: matrix.configuration == 'release' diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 93daa6d31a..1886a05af7 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -23,17 +23,17 @@ jobs: fetch-depth: 0 - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} - - name: Setup .NET - uses: actions/setup-dotnet@v3 + - uses: actions/setup-dotnet@v4 with: - dotnet-version: 6.0.x + dotnet-version: '8.0.x' + dotnet-quality: 'ga' - name: Build run: dotnet build ILSpy.XPlat.slnf --configuration Release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/lock.yml b/.github/workflows/lock.yml index f3de4cb41f..3bc404b704 100644 --- a/.github/workflows/lock.yml +++ b/.github/workflows/lock.yml @@ -8,7 +8,7 @@ jobs: lock: runs-on: ubuntu-latest steps: - - uses: dessant/lock-threads@v4.0.1 + - uses: dessant/lock-threads@v5.0.1 with: github-token: ${{ github.token }} issue-inactive-days: '90' diff --git a/Directory.Packages.props b/Directory.Packages.props new file mode 100644 index 0000000000..a8c2b5f8e0 --- /dev/null +++ b/Directory.Packages.props @@ -0,0 +1,46 @@ + + + true + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ICSharpCode.Decompiler.PowerShell/ICSharpCode.Decompiler.PowerShell.csproj b/ICSharpCode.Decompiler.PowerShell/ICSharpCode.Decompiler.PowerShell.csproj index c50801c161..f5d58901fe 100644 --- a/ICSharpCode.Decompiler.PowerShell/ICSharpCode.Decompiler.PowerShell.csproj +++ b/ICSharpCode.Decompiler.PowerShell/ICSharpCode.Decompiler.PowerShell.csproj @@ -8,11 +8,9 @@ 8.0 - - - - + + diff --git a/ICSharpCode.Decompiler.TestRunner/ICSharpCode.Decompiler.TestRunner.csproj b/ICSharpCode.Decompiler.TestRunner/ICSharpCode.Decompiler.TestRunner.csproj index 8c8d40ddc3..af31fefa23 100644 --- a/ICSharpCode.Decompiler.TestRunner/ICSharpCode.Decompiler.TestRunner.csproj +++ b/ICSharpCode.Decompiler.TestRunner/ICSharpCode.Decompiler.TestRunner.csproj @@ -2,7 +2,7 @@ Exe - net7.0 + net8.0 enable diff --git a/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs b/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs index ed4a3f2bb2..5246e5d27b 100644 --- a/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs @@ -46,7 +46,7 @@ public void AllFilesHaveTests() if (file.Extension == ".txt" || file.Extension == ".exe" || file.Extension == ".config") continue; var testName = Path.GetFileNameWithoutExtension(file.Name); - Assert.Contains(testName, testNames); + Assert.That(testNames, Has.Member(testName)); } } @@ -486,7 +486,7 @@ async Task RunIL(string testFileName, CompilerOptions options = CompilerOptions. bool optionsForce32Bit = options.HasFlag(CompilerOptions.Force32Bit); bool asmOptionsForce32Bit = asmOptions.HasFlag(AssemblerOptions.Force32Bit); - Assert.AreEqual(optionsForce32Bit, asmOptionsForce32Bit, "Inconsistent architecture."); + Assert.That(asmOptionsForce32Bit, Is.EqualTo(optionsForce32Bit), "Inconsistent architecture."); try { diff --git a/ICSharpCode.Decompiler.Tests/DataFlowTest.cs b/ICSharpCode.Decompiler.Tests/DataFlowTest.cs index cfe14be750..7a1c200fa9 100644 --- a/ICSharpCode.Decompiler.Tests/DataFlowTest.cs +++ b/ICSharpCode.Decompiler.Tests/DataFlowTest.cs @@ -45,11 +45,11 @@ public RDTest(ILFunction f, ILVariable v) : base(f, _ => true, CancellationToken protected internal override void VisitTryFinally(TryFinally inst) { - Assert.IsTrue(IsPotentiallyUninitialized(state, v)); + Assert.That(IsPotentiallyUninitialized(state, v)); base.VisitTryFinally(inst); - Assert.IsTrue(state.IsReachable); - Assert.AreEqual(1, GetStores(state, v).Count()); - Assert.IsFalse(IsPotentiallyUninitialized(state, v)); + Assert.That(state.IsReachable); + Assert.That(GetStores(state, v).Count(), Is.EqualTo(1)); + Assert.That(!IsPotentiallyUninitialized(state, v)); } } diff --git a/ICSharpCode.Decompiler.Tests/DisassemblerPrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/DisassemblerPrettyTestRunner.cs index 9636facc1c..9fa9e7e855 100644 --- a/ICSharpCode.Decompiler.Tests/DisassemblerPrettyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/DisassemblerPrettyTestRunner.cs @@ -47,7 +47,7 @@ public void AllFilesHaveTests() if (file.Extension.Equals(".il", StringComparison.OrdinalIgnoreCase)) { var testName = file.Name.Split('.')[0]; - Assert.Contains(testName, testNames); + Assert.That(testNames, Has.Member(testName)); } } } diff --git a/ICSharpCode.Decompiler.Tests/Helpers/Tester.VB.cs b/ICSharpCode.Decompiler.Tests/Helpers/Tester.VB.cs index 2c84b6180e..6b8e403e37 100644 --- a/ICSharpCode.Decompiler.Tests/Helpers/Tester.VB.cs +++ b/ICSharpCode.Decompiler.Tests/Helpers/Tester.VB.cs @@ -133,7 +133,7 @@ public static async Task CompileVB(string sourceFileName, Compi { Console.WriteLine("errors:" + Environment.NewLine + result.StandardError); } - Assert.AreEqual(0, result.ExitCode, "vbc failed"); + Assert.That(result.ExitCode, Is.EqualTo(0), "vbc failed"); return results; } diff --git a/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs b/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs index cd3f185dad..ecbcf5c1b7 100644 --- a/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs +++ b/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs @@ -105,12 +105,19 @@ static Tester() TesterPath = Path.GetDirectoryName(typeof(Tester).Assembly.Location); TestCasePath = Path.Combine(TesterPath, "../../../../TestCases"); #if DEBUG - testRunnerBasePath = Path.Combine(TesterPath, "../../../../../ICSharpCode.Decompiler.TestRunner/bin/Debug/net7.0"); + testRunnerBasePath = Path.Combine(TesterPath, "../../../../../ICSharpCode.Decompiler.TestRunner/bin/Debug/net8.0"); #else - testRunnerBasePath = Path.Combine(TesterPath, "../../../../../ICSharpCode.Decompiler.TestRunner/bin/Release/net7.0"); + testRunnerBasePath = Path.Combine(TesterPath, "../../../../../ICSharpCode.Decompiler.TestRunner/bin/Release/net8.0"); #endif - packagesPropsFile = Path.Combine(TesterPath, "../../../../../packages.props"); - roslynLatestVersion = XDocument.Load(packagesPropsFile).XPathSelectElement("//RoslynVersion").Value; + // To parse: + packagesPropsFile = Path.Combine(TesterPath, "../../../../../Directory.Packages.props"); + roslynLatestVersion = ((IEnumerable)(XDocument + .Load(packagesPropsFile) + .XPathEvaluate("//Project//ItemGroup//PackageVersion[@Include='Microsoft.CodeAnalysis.CSharp']/@Version"))) + .OfType() + .Single() + .Value; + roslynToolset = new RoslynToolset(); vswhereToolset = new VsWhereToolset(); } @@ -191,7 +198,7 @@ public static async Task AssembleIL(string sourceFileName, AssemblerOpti { Console.WriteLine("errors:" + Environment.NewLine + result.StandardError); } - Assert.AreEqual(0, result.ExitCode, "ilasm failed"); + Assert.That(result.ExitCode, Is.EqualTo(0), "ilasm failed"); return outputFile; } @@ -244,7 +251,7 @@ public static async Task Disassemble(string sourceFileName, string outpu { Console.WriteLine("errors:" + Environment.NewLine + result.StandardError); } - Assert.AreEqual(0, result.ExitCode, "ildasm failed"); + Assert.That(result.ExitCode, Is.EqualTo(0), "ildasm failed"); // Unlike the .imagebase directive (which is a fixed value when compiling with /deterministic), // the image base comment still varies... ildasm putting a random number here? @@ -270,8 +277,8 @@ private static string ReplacePrivImplDetails(string il) } static readonly string coreRefAsmPath = new DotNetCorePathFinder(TargetFrameworkIdentifier.NET, - new Version(7, 0), "Microsoft.NETCore.App") - .GetReferenceAssemblyPath(".NETCoreApp,Version=v7.0"); + new Version(8, 0), "Microsoft.NETCore.App") + .GetReferenceAssemblyPath(".NETCoreApp,Version=v8.0"); public static readonly string RefAsmPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), @"Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2"); @@ -309,7 +316,7 @@ private static string ReplacePrivImplDetails(string il) const string targetFrameworkAttributeSnippet = @" -[assembly: System.Runtime.Versioning.TargetFramework("".NETCoreApp,Version=v7.0"", FrameworkDisplayName = """")] +[assembly: System.Runtime.Versioning.TargetFramework("".NETCoreApp,Version=v8.0"", FrameworkDisplayName = """")] "; @@ -345,6 +352,7 @@ public static List GetPreprocessorSymbols(CompilerOptions flags) preprocessorSymbols.Add("NETCORE"); preprocessorSymbols.Add("NET60"); preprocessorSymbols.Add("NET70"); + preprocessorSymbols.Add("NET80"); } preprocessorSymbols.Add("ROSLYN"); preprocessorSymbols.Add("CS60"); @@ -374,6 +382,7 @@ public static List GetPreprocessorSymbols(CompilerOptions flags) preprocessorSymbols.Add("ROSLYN4"); preprocessorSymbols.Add("CS100"); preprocessorSymbols.Add("CS110"); + preprocessorSymbols.Add("CS120"); } } else if ((flags & CompilerOptions.UseMcsMask) != 0) @@ -511,7 +520,7 @@ public static async Task CompileCSharp(string sourceFileName, C Console.WriteLine("errors:" + Environment.NewLine + result.StandardError); } - Assert.AreEqual(0, result.ExitCode, "csc failed"); + Assert.That(result.ExitCode, Is.EqualTo(0), "csc failed"); return results; } @@ -573,7 +582,7 @@ public static async Task CompileCSharp(string sourceFileName, C { Console.WriteLine("errors:" + Environment.NewLine + result.StandardError); } - Assert.AreEqual(0, result.ExitCode, "mcs failed"); + Assert.That(result.ExitCode, Is.EqualTo(0), "mcs failed"); return results; } @@ -755,8 +764,8 @@ public static async Task RunAndCompareOutput(string testFileName, string outputF (result2, output2, error2) = await Run(decompiledOutputFile).ConfigureAwait(false); } - Assert.AreEqual(0, result1, "Exit code != 0; did the test case crash?" + Environment.NewLine + error1); - Assert.AreEqual(0, result2, "Exit code != 0; did the decompiled code crash?" + Environment.NewLine + error2); + Assert.That(result1, Is.EqualTo(0), "Exit code != 0; did the test case crash?" + Environment.NewLine + error1); + Assert.That(result2, Is.EqualTo(0), "Exit code != 0; did the decompiled code crash?" + Environment.NewLine + error2); if (output1 != output2 || error1 != error2) { @@ -842,7 +851,7 @@ public static async Task SignAssembly(string assemblyPath, string keyFilePath) .WithValidation(CommandResultValidation.None); var result = await command.ExecuteBufferedAsync().ConfigureAwait(false); - Assert.AreEqual(0, result.ExitCode, "sn failed"); + Assert.That(result.ExitCode, Is.EqualTo(0), "sn failed"); if (!string.IsNullOrWhiteSpace(result.StandardOutput)) { diff --git a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj index 8ca93f4916..1dfb43ed0d 100644 --- a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj +++ b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj @@ -2,7 +2,7 @@ - net6.0-windows + net8.0-windows win-x64 false AutoGeneratedProgram @@ -17,7 +17,6 @@ false True - True True ..\ICSharpCode.Decompiler\ICSharpCode.Decompiler.snk @@ -41,28 +40,28 @@ TRACE;ROSLYN;NET60;CS60;CS70;CS71;CS72;CS73;CS80;CS90;CS100 - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + diff --git a/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs index 6a2cc4ed34..04c94d0898 100644 --- a/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs @@ -45,8 +45,8 @@ public void AllFilesHaveTests() if (file.Extension.Equals(".il", StringComparison.OrdinalIgnoreCase)) { var testName = file.Name.Split('.')[0]; - Assert.Contains(testName, testNames); - Assert.IsTrue(File.Exists(Path.Combine(TestCasePath, testName + ".cs"))); + Assert.That(testNames, Has.Member(testName)); + Assert.That(File.Exists(Path.Combine(TestCasePath, testName + ".cs"))); } } } diff --git a/ICSharpCode.Decompiler.Tests/Output/CSharpAmbienceTests.cs b/ICSharpCode.Decompiler.Tests/Output/CSharpAmbienceTests.cs index f729215c4e..63eec4cd39 100644 --- a/ICSharpCode.Decompiler.Tests/Output/CSharpAmbienceTests.cs +++ b/ICSharpCode.Decompiler.Tests/Output/CSharpAmbienceTests.cs @@ -55,7 +55,7 @@ ITypeDefinition GetDefinition(Type type) } var foundType = compilation.FindType(type).GetDefinition(); - Assert.IsNotNull(foundType); + Assert.That(foundType, Is.Not.Null); return foundType; } @@ -76,7 +76,7 @@ public void GenericType(ConversionFlags flags, string expectedOutput) { var typeDef = GetDefinition(typeof(Dictionary<,>)); ambience.ConversionFlags = flags; - Assert.AreEqual(expectedOutput, ambience.ConvertSymbol(typeDef)); + Assert.That(ambience.ConvertSymbol(typeDef), Is.EqualTo(expectedOutput)); } [TestCase(None, "Object")] @@ -92,7 +92,7 @@ public void SimpleType(ConversionFlags flags, string expectedOutput) { var typeDef = GetDefinition(typeof(object)); ambience.ConversionFlags = flags; - Assert.AreEqual(expectedOutput, ambience.ConvertSymbol(typeDef)); + Assert.That(ambience.ConvertSymbol(typeDef), Is.EqualTo(expectedOutput)); } [TestCase(None, "IEnumerable")] @@ -104,7 +104,7 @@ public void GenericInterface(ConversionFlags flags, string expectedOutput) { var typeDef = GetDefinition(typeof(IEnumerable<>)); ambience.ConversionFlags = flags; - Assert.AreEqual(expectedOutput, ambience.ConvertSymbol(typeDef)); + Assert.That(ambience.ConvertSymbol(typeDef), Is.EqualTo(expectedOutput)); } [TestCase(None, "Enumerator")] @@ -121,7 +121,7 @@ public void GenericTypeWithNested(ConversionFlags flags, string expectedOutput) { var typeDef = GetDefinition(typeof(List<>.Enumerator)); ambience.ConversionFlags = flags; - Assert.AreEqual(expectedOutput, ambience.ConvertSymbol(typeDef)); + Assert.That(ambience.ConvertSymbol(typeDef), Is.EqualTo(expectedOutput)); } [TestCase(None, "StaticClass")] @@ -137,7 +137,7 @@ public void StaticClassTest(ConversionFlags flags, string expectedOutput) { var typeDef = GetDefinition(typeof(StaticClass)); ambience.ConversionFlags = flags; - Assert.AreEqual(expectedOutput, ambience.ConvertSymbol(typeDef)); + Assert.That(ambience.ConvertSymbol(typeDef), Is.EqualTo(expectedOutput)); } [TestCase(None, "SealedClass")] @@ -153,7 +153,7 @@ public void SealedClassTest(ConversionFlags flags, string expectedOutput) { var typeDef = GetDefinition(typeof(SealedClass)); ambience.ConversionFlags = flags; - Assert.AreEqual(expectedOutput, ambience.ConvertSymbol(typeDef)); + Assert.That(ambience.ConvertSymbol(typeDef), Is.EqualTo(expectedOutput)); } [TestCase(None, "RefStruct")] @@ -169,7 +169,7 @@ public void RefStructTest(ConversionFlags flags, string expectedOutput) { var typeDef = GetDefinition(typeof(RefStruct)); ambience.ConversionFlags = flags; - Assert.AreEqual(expectedOutput, ambience.ConvertSymbol(typeDef)); + Assert.That(ambience.ConvertSymbol(typeDef), Is.EqualTo(expectedOutput)); } [TestCase(None, "ReadonlyStruct")] @@ -185,7 +185,7 @@ public void ReadonlyStructTest(ConversionFlags flags, string expectedOutput) { var typeDef = GetDefinition(typeof(ReadonlyStruct)); ambience.ConversionFlags = flags; - Assert.AreEqual(expectedOutput, ambience.ConvertSymbol(typeDef)); + Assert.That(ambience.ConvertSymbol(typeDef), Is.EqualTo(expectedOutput)); } [TestCase(None, "ReadonlyRefStruct")] @@ -201,7 +201,7 @@ public void ReadonlyRefStructTest(ConversionFlags flags, string expectedOutput) { var typeDef = GetDefinition(typeof(ReadonlyRefStruct)); ambience.ConversionFlags = flags; - Assert.AreEqual(expectedOutput, ambience.ConvertSymbol(typeDef)); + Assert.That(ambience.ConvertSymbol(typeDef), Is.EqualTo(expectedOutput)); } #endregion @@ -219,7 +219,7 @@ public void FuncDelegate(ConversionFlags flags, string expectedOutput) { var func = GetDefinition(typeof(Func<,>)); ambience.ConversionFlags = flags; - Assert.AreEqual(expectedOutput, ambience.ConvertSymbol(func)); + Assert.That(ambience.ConvertSymbol(func), Is.EqualTo(expectedOutput)); } #endregion @@ -232,7 +232,7 @@ public void SimpleField(ConversionFlags flags, string expectedOutput) var field = GetDefinition(typeof(CSharpAmbienceTests.Program)).GetFields(f => f.Name == "test").Single(); ambience.ConversionFlags = flags; - Assert.AreEqual(expectedOutput, ambience.ConvertSymbol(field)); + Assert.That(ambience.ConvertSymbol(field), Is.EqualTo(expectedOutput)); } [TestCase(All & ~PlaceReturnTypeAfterParameterList, "private const int ICSharpCode.Decompiler.Tests.Output.CSharpAmbienceTests.Program.TEST2;")] @@ -242,7 +242,7 @@ public void SimpleConstField(ConversionFlags flags, string expectedOutput) var field = compilation.FindType(typeof(CSharpAmbienceTests.Program)).GetFields(f => f.Name == "TEST2").Single(); ambience.ConversionFlags = flags; - Assert.AreEqual(expectedOutput, ambience.ConvertSymbol(field)); + Assert.That(ambience.ConvertSymbol(field), Is.EqualTo(expectedOutput)); } #endregion @@ -254,7 +254,7 @@ public void EventWithDeclaringType() ambience.ConversionFlags = ConversionFlags.StandardConversionFlags | ConversionFlags.ShowDeclaringType; string result = ambience.ConvertSymbol(ev); - Assert.AreEqual("public event EventHandler Program.ProgramChanged;", result); + Assert.That(result, Is.EqualTo("public event EventHandler Program.ProgramChanged;")); } [Test] @@ -264,7 +264,7 @@ public void CustomEvent() ambience.ConversionFlags = ConversionFlags.StandardConversionFlags; string result = ambience.ConvertSymbol(ev); - Assert.AreEqual("public event EventHandler SomeEvent;", result); + Assert.That(result, Is.EqualTo("public event EventHandler SomeEvent;")); } #endregion @@ -276,7 +276,7 @@ public void AutomaticProperty(ConversionFlags flags, string expectedOutput) var prop = compilation.FindType(typeof(CSharpAmbienceTests.Program)).GetProperties(p => p.Name == "Test").Single(); ambience.ConversionFlags = flags; - Assert.AreEqual(expectedOutput, ambience.ConvertSymbol(prop)); + Assert.That(ambience.ConvertSymbol(prop), Is.EqualTo(expectedOutput)); } [TestCase(StandardConversionFlags, "public int this[int index] { get; }")] @@ -286,7 +286,7 @@ public void Indexer(ConversionFlags flags, string expectedOutput) var prop = compilation.FindType(typeof(CSharpAmbienceTests.Program)).GetProperties(p => p.IsIndexer).Single(); ambience.ConversionFlags = flags; - Assert.AreEqual(expectedOutput, ambience.ConvertSymbol(prop)); + Assert.That(ambience.ConvertSymbol(prop), Is.EqualTo(expectedOutput)); } #endregion @@ -298,7 +298,7 @@ public void ConstructorTests(ConversionFlags flags, string expectedOutput) var prop = compilation.FindType(typeof(CSharpAmbienceTests.Program)).GetConstructors().Single(); ambience.ConversionFlags = flags; - Assert.AreEqual(expectedOutput, ambience.ConvertSymbol(prop)); + Assert.That(ambience.ConvertSymbol(prop), Is.EqualTo(expectedOutput)); } [TestCase(StandardConversionFlags, "~Program();")] @@ -309,7 +309,7 @@ public void DestructorTests(ConversionFlags flags, string expectedOutput) .GetMembers(m => m.SymbolKind == SymbolKind.Destructor, GetMemberOptions.IgnoreInheritedMembers).Single(); ambience.ConversionFlags = flags; - Assert.AreEqual(expectedOutput, ambience.ConvertSymbol(dtor)); + Assert.That(ambience.ConvertSymbol(dtor), Is.EqualTo(expectedOutput)); } #endregion diff --git a/ICSharpCode.Decompiler.Tests/Output/InsertParenthesesVisitorTests.cs b/ICSharpCode.Decompiler.Tests/Output/InsertParenthesesVisitorTests.cs index f9bb5ddef0..0e7a3f3160 100644 --- a/ICSharpCode.Decompiler.Tests/Output/InsertParenthesesVisitorTests.cs +++ b/ICSharpCode.Decompiler.Tests/Output/InsertParenthesesVisitorTests.cs @@ -68,8 +68,8 @@ public void EqualityInAssignment() ) ); - Assert.AreEqual("cond = a == b", InsertRequired(expr)); - Assert.AreEqual("cond = a == b", InsertReadable(expr)); + Assert.That(InsertRequired(expr), Is.EqualTo("cond = a == b")); + Assert.That(InsertReadable(expr), Is.EqualTo("cond = a == b")); } [Test] @@ -86,8 +86,8 @@ public void LambdaInAssignment() } ); - Assert.AreEqual("p = () => a + b", InsertRequired(expr)); - Assert.AreEqual("p = () => a + b", InsertReadable(expr)); + Assert.That(InsertRequired(expr), Is.EqualTo("p = () => a + b")); + Assert.That(InsertReadable(expr), Is.EqualTo("p = () => a + b")); } [Test] @@ -105,8 +105,8 @@ public void LambdaInDelegateAdditionRHS() } }; - Assert.AreEqual("p + () => a + b", InsertRequired(expr)); - Assert.AreEqual("p + (() => a + b)", InsertReadable(expr)); + Assert.That(InsertRequired(expr), Is.EqualTo("p + () => a + b")); + Assert.That(InsertReadable(expr), Is.EqualTo("p + (() => a + b)")); } [Test] @@ -124,8 +124,8 @@ public void LambdaInDelegateAdditionLHS() Right = new IdentifierExpression("p"), }; - Assert.AreEqual("(() => a + b) + p", InsertRequired(expr)); - Assert.AreEqual("(() => a + b) + p", InsertReadable(expr)); + Assert.That(InsertRequired(expr), Is.EqualTo("(() => a + b) + p")); + Assert.That(InsertReadable(expr), Is.EqualTo("(() => a + b) + p")); } [Test] @@ -138,8 +138,8 @@ public void TrickyCast1() ) }; - Assert.AreEqual("(int)-a", InsertRequired(expr)); - Assert.AreEqual("(int)(-a)", InsertReadable(expr)); + Assert.That(InsertRequired(expr), Is.EqualTo("(int)-a")); + Assert.That(InsertReadable(expr), Is.EqualTo("(int)(-a)")); } [Test] @@ -152,8 +152,8 @@ public void TrickyCast2() ) }; - Assert.AreEqual("(MyType)(-a)", InsertRequired(expr)); - Assert.AreEqual("(MyType)(-a)", InsertReadable(expr)); + Assert.That(InsertRequired(expr), Is.EqualTo("(MyType)(-a)")); + Assert.That(InsertReadable(expr), Is.EqualTo("(MyType)(-a)")); } [Test] @@ -166,8 +166,8 @@ public void TrickyCast3() ) }; - Assert.AreEqual("(MyType)!a", InsertRequired(expr)); - Assert.AreEqual("(MyType)(!a)", InsertReadable(expr)); + Assert.That(InsertRequired(expr), Is.EqualTo("(MyType)!a")); + Assert.That(InsertReadable(expr), Is.EqualTo("(MyType)(!a)")); } [Test] @@ -178,8 +178,8 @@ public void TrickyCast4() Expression = new PrimitiveExpression(int.MinValue), }; - Assert.AreEqual("(MyType)(-2147483648)", InsertRequired(expr)); - Assert.AreEqual("(MyType)(-2147483648)", InsertReadable(expr)); + Assert.That(InsertRequired(expr), Is.EqualTo("(MyType)(-2147483648)")); + Assert.That(InsertReadable(expr), Is.EqualTo("(MyType)(-2147483648)")); } [Test] @@ -190,8 +190,8 @@ public void TrickyCast5() Expression = new PrimitiveExpression(-1.0), }; - Assert.AreEqual("(MyType)(-1.0)", InsertRequired(expr)); - Assert.AreEqual("(MyType)(-1.0)", InsertReadable(expr)); + Assert.That(InsertRequired(expr), Is.EqualTo("(MyType)(-1.0)")); + Assert.That(InsertReadable(expr), Is.EqualTo("(MyType)(-1.0)")); } [Test] @@ -202,8 +202,8 @@ public void TrickyCast6() Expression = new PrimitiveExpression(int.MinValue), }; - Assert.AreEqual("(double)-2147483648", InsertRequired(expr)); - Assert.AreEqual("(double)(-2147483648)", InsertReadable(expr)); + Assert.That(InsertRequired(expr), Is.EqualTo("(double)-2147483648")); + Assert.That(InsertReadable(expr), Is.EqualTo("(double)(-2147483648)")); } [Test] @@ -217,8 +217,8 @@ public void CastAndInvoke() MemberName = "Length" }; - Assert.AreEqual("((string)a).Length", InsertRequired(expr)); - Assert.AreEqual("((string)a).Length", InsertReadable(expr)); + Assert.That(InsertRequired(expr), Is.EqualTo("((string)a).Length")); + Assert.That(InsertReadable(expr), Is.EqualTo("((string)a).Length")); } [Test] @@ -229,8 +229,8 @@ public void DoubleNegation() new UnaryOperatorExpression(UnaryOperatorType.Minus, new IdentifierExpression("a")) ); - Assert.AreEqual("- -a", InsertRequired(expr)); - Assert.AreEqual("-(-a)", InsertReadable(expr)); + Assert.That(InsertRequired(expr), Is.EqualTo("- -a")); + Assert.That(InsertReadable(expr), Is.EqualTo("-(-a)")); } [Test] @@ -250,8 +250,8 @@ public void AdditionWithConditional() } }; - Assert.AreEqual("a + (b == null ? c : d)", InsertRequired(expr)); - Assert.AreEqual("a + ((b == null) ? c : d)", InsertReadable(expr)); + Assert.That(InsertRequired(expr), Is.EqualTo("a + (b == null ? c : d)")); + Assert.That(InsertReadable(expr), Is.EqualTo("a + ((b == null) ? c : d)")); } [Test] @@ -269,16 +269,16 @@ public void TypeTestInConditional() FalseExpression = new IdentifierExpression("c") }; - Assert.AreEqual("a is int? ? b : c", InsertRequired(expr)); - Assert.AreEqual("(a is int?) ? b : c", InsertReadable(expr)); + Assert.That(InsertRequired(expr), Is.EqualTo("a is int? ? b : c")); + Assert.That(InsertReadable(expr), Is.EqualTo("(a is int?) ? b : c")); policy.SpaceBeforeConditionalOperatorCondition = false; policy.SpaceAfterConditionalOperatorCondition = false; policy.SpaceBeforeConditionalOperatorSeparator = false; policy.SpaceAfterConditionalOperatorSeparator = false; - Assert.AreEqual("a is int? ?b:c", InsertRequired(expr)); - Assert.AreEqual("(a is int?)?b:c", InsertReadable(expr)); + Assert.That(InsertRequired(expr), Is.EqualTo("a is int? ?b:c")); + Assert.That(InsertReadable(expr), Is.EqualTo("(a is int?)?b:c")); } [Test] @@ -302,8 +302,8 @@ public void MethodCallOnQueryExpression() MemberName = "ToArray" }); - Assert.AreEqual("(from a in b select a.c ()).ToArray ()", InsertRequired(expr)); - Assert.AreEqual("(from a in b select a.c ()).ToArray ()", InsertReadable(expr)); + Assert.That(InsertRequired(expr), Is.EqualTo("(from a in b select a.c ()).ToArray ()")); + Assert.That(InsertReadable(expr), Is.EqualTo("(from a in b select a.c ()).ToArray ()")); } [Test] @@ -326,10 +326,10 @@ public void SumOfQueries() query.Clone() ); - Assert.AreEqual("(from a in b select a) + " + - "from a in b select a", InsertRequired(expr)); - Assert.AreEqual("(from a in b select a) + " + - "(from a in b select a)", InsertReadable(expr)); + Assert.That(InsertRequired(expr), Is.EqualTo("(from a in b select a) + " + + "from a in b select a")); + Assert.That(InsertReadable(expr), Is.EqualTo("(from a in b select a) + " + + "(from a in b select a)")); } [Test] @@ -350,8 +350,8 @@ public void QueryInTypeTest() Type = new PrimitiveType("int") }; - Assert.AreEqual("(from a in b select a) is int", InsertRequired(expr)); - Assert.AreEqual("(from a in b select a) is int", InsertReadable(expr)); + Assert.That(InsertRequired(expr), Is.EqualTo("(from a in b select a) is int")); + Assert.That(InsertReadable(expr), Is.EqualTo("(from a in b select a) is int")); } [Test] @@ -365,8 +365,8 @@ public void PrePost() ) ); - Assert.AreEqual("++a++", InsertRequired(expr)); - Assert.AreEqual("++(a++)", InsertReadable(expr)); + Assert.That(InsertRequired(expr), Is.EqualTo("++a++")); + Assert.That(InsertReadable(expr), Is.EqualTo("++(a++)")); } [Test] @@ -380,8 +380,8 @@ public void PostPre() ) ); - Assert.AreEqual("(++a)++", InsertRequired(expr)); - Assert.AreEqual("(++a)++", InsertReadable(expr)); + Assert.That(InsertRequired(expr), Is.EqualTo("(++a)++")); + Assert.That(InsertReadable(expr), Is.EqualTo("(++a)++")); } [Test] @@ -397,8 +397,8 @@ public void Logical1() new IdentifierExpression("c") ); - Assert.AreEqual("a && b && c", InsertRequired(expr)); - Assert.AreEqual("a && b && c", InsertReadable(expr)); + Assert.That(InsertRequired(expr), Is.EqualTo("a && b && c")); + Assert.That(InsertReadable(expr), Is.EqualTo("a && b && c")); } [Test] @@ -414,8 +414,8 @@ public void Logical2() ) ); - Assert.AreEqual("a && (b && c)", InsertRequired(expr)); - Assert.AreEqual("a && (b && c)", InsertReadable(expr)); + Assert.That(InsertRequired(expr), Is.EqualTo("a && (b && c)")); + Assert.That(InsertReadable(expr), Is.EqualTo("a && (b && c)")); } [Test] @@ -431,8 +431,8 @@ public void Logical3() ) ); - Assert.AreEqual("a || b && c", InsertRequired(expr)); - Assert.AreEqual("a || (b && c)", InsertReadable(expr)); + Assert.That(InsertRequired(expr), Is.EqualTo("a || b && c")); + Assert.That(InsertReadable(expr), Is.EqualTo("a || (b && c)")); } [Test] @@ -448,8 +448,8 @@ public void Logical4() ) ); - Assert.AreEqual("a && (b || c)", InsertRequired(expr)); - Assert.AreEqual("a && (b || c)", InsertReadable(expr)); + Assert.That(InsertRequired(expr), Is.EqualTo("a && (b || c)")); + Assert.That(InsertReadable(expr), Is.EqualTo("a && (b || c)")); } [Test] @@ -463,8 +463,8 @@ public void ArrayCreationInIndexer() Arguments = { new PrimitiveExpression(0) } }; - Assert.AreEqual("(new int[1]) [0]", InsertRequired(expr)); - Assert.AreEqual("(new int[1]) [0]", InsertReadable(expr)); + Assert.That(InsertRequired(expr), Is.EqualTo("(new int[1]) [0]")); + Assert.That(InsertReadable(expr), Is.EqualTo("(new int[1]) [0]")); } [Test] @@ -481,8 +481,8 @@ public void ArrayCreationWithInitializerInIndexer() Arguments = { new PrimitiveExpression(0) } }; - Assert.AreEqual("new int[1] { 42 } [0]", InsertRequired(expr)); - Assert.AreEqual("(new int[1] { 42 }) [0]", InsertReadable(expr)); + Assert.That(InsertRequired(expr), Is.EqualTo("new int[1] { 42 } [0]")); + Assert.That(InsertReadable(expr), Is.EqualTo("(new int[1] { 42 }) [0]")); } } } diff --git a/ICSharpCode.Decompiler.Tests/PdbGenerationTestRunner.cs b/ICSharpCode.Decompiler.Tests/PdbGenerationTestRunner.cs index ed8488fa43..48dda98649 100644 --- a/ICSharpCode.Decompiler.Tests/PdbGenerationTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/PdbGenerationTestRunner.cs @@ -70,8 +70,8 @@ public void CustomPdbId() var metadataReader = MetadataReaderProvider.FromPortablePdbStream(pdbStream).GetMetadataReader(); var generatedPdbId = new BlobContentId(metadataReader.DebugMetadataHeader.Id); - Assert.AreEqual(expectedPdbId.Guid, generatedPdbId.Guid); - Assert.AreEqual(expectedPdbId.Stamp, generatedPdbId.Stamp); + Assert.That(generatedPdbId.Guid, Is.EqualTo(expectedPdbId.Guid)); + Assert.That(generatedPdbId.Stamp, Is.EqualTo(expectedPdbId.Stamp)); } } @@ -95,8 +95,8 @@ public void ProgressReporting() totalFiles = progress.TotalUnits; } - Assert.AreEqual(progress.TotalUnits, totalFiles); - Assert.AreEqual(progress.UnitsCompleted, lastFilesWritten + 1); + Assert.That(totalFiles, Is.EqualTo(progress.TotalUnits)); + Assert.That(lastFilesWritten + 1, Is.EqualTo(progress.UnitsCompleted)); lastFilesWritten = progress.UnitsCompleted; }; @@ -111,7 +111,7 @@ public void ProgressReporting() var generatedPdbId = new BlobContentId(metadataReader.DebugMetadataHeader.Id); } - Assert.AreEqual(totalFiles, lastFilesWritten); + Assert.That(lastFilesWritten, Is.EqualTo(totalFiles)); } private class TestProgressReporter : IProgress diff --git a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs index c341835e0e..4fe48369dd 100644 --- a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs @@ -46,7 +46,7 @@ public void AllFilesHaveTests() || file.Extension.Equals(".cs", StringComparison.OrdinalIgnoreCase)) { var testName = file.Name.Split('.')[0]; - Assert.Contains(testName, testNames); + Assert.That(testNames, Has.Member(testName)); } } } diff --git a/ICSharpCode.Decompiler.Tests/ProjectDecompiler/TargetFrameworkTests.cs b/ICSharpCode.Decompiler.Tests/ProjectDecompiler/TargetFrameworkTests.cs index c92f49c574..df78e9bc1b 100644 --- a/ICSharpCode.Decompiler.Tests/ProjectDecompiler/TargetFrameworkTests.cs +++ b/ICSharpCode.Decompiler.Tests/ProjectDecompiler/TargetFrameworkTests.cs @@ -57,8 +57,8 @@ public void VerifyVersion(int version, string expectedVersion) var targetFramework = new TargetFramework(identifier: null, version, profile: null); // Assert - Assert.AreEqual(version, targetFramework.VersionNumber); - Assert.AreEqual(expectedVersion, targetFramework.VersionString); + Assert.That(targetFramework.VersionNumber, Is.EqualTo(version)); + Assert.That(targetFramework.VersionString, Is.EqualTo(expectedVersion)); } [Test] @@ -71,8 +71,8 @@ public void VerifyPortableLibrary() var targetFramework = new TargetFramework(identifier, 100, profile: null); // Assert - Assert.IsTrue(targetFramework.IsPortableClassLibrary); - Assert.AreEqual(identifier, targetFramework.Identifier); + Assert.That(targetFramework.IsPortableClassLibrary); + Assert.That(targetFramework.Identifier, Is.EqualTo(identifier)); } [Test] @@ -87,8 +87,8 @@ public void VerifyIdentifierAndProfile( var targetFramework = new TargetFramework(identifier, 100, profile); // Assert - Assert.AreEqual(identifier, targetFramework.Identifier); - Assert.AreEqual(profile, targetFramework.Profile); + Assert.That(targetFramework.Identifier, Is.EqualTo(identifier)); + Assert.That(targetFramework.Profile, Is.EqualTo(profile)); } [TestCase(null, 350, "net35")] @@ -117,7 +117,7 @@ public void VerifyMoniker(string identifier, int version, string expectedMoniker var targetFramework = new TargetFramework(identifier, version, profile: null); // Assert - Assert.AreEqual(expectedMoniker, targetFramework.Moniker); + Assert.That(targetFramework.Moniker, Is.EqualTo(expectedMoniker)); } } } diff --git a/ICSharpCode.Decompiler.Tests/RoundtripAssembly.cs b/ICSharpCode.Decompiler.Tests/RoundtripAssembly.cs index 3a378e2374..d65300b7c0 100644 --- a/ICSharpCode.Decompiler.Tests/RoundtripAssembly.cs +++ b/ICSharpCode.Decompiler.Tests/RoundtripAssembly.cs @@ -212,7 +212,7 @@ async Task RunInternal(string dir, string fileToRoundtrip, Action testAc File.Copy(file, Path.Combine(outputDir, relFile)); } } - Assert.IsNotNull(projectFile, $"Could not find {fileToRoundtrip}"); + Assert.That(projectFile, Is.Not.Null, $"Could not find {fileToRoundtrip}"); await Compile(projectFile, outputDir); testAction(outputDir); diff --git a/ICSharpCode.Decompiler.Tests/Semantics/ConversionTests.cs b/ICSharpCode.Decompiler.Tests/Semantics/ConversionTests.cs index a6687124c5..8484cd2665 100644 --- a/ICSharpCode.Decompiler.Tests/Semantics/ConversionTests.cs +++ b/ICSharpCode.Decompiler.Tests/Semantics/ConversionTests.cs @@ -70,34 +70,34 @@ Conversion ExplicitConversion(Type from, Type to) [Test] public void IdentityConversions() { - Assert.AreEqual(C.IdentityConversion, ImplicitConversion(typeof(char), typeof(char))); - Assert.AreEqual(C.IdentityConversion, ImplicitConversion(typeof(string), typeof(string))); - Assert.AreEqual(C.IdentityConversion, ImplicitConversion(typeof(object), typeof(object))); - Assert.AreEqual(C.None, ImplicitConversion(typeof(bool), typeof(char))); + Assert.That(ImplicitConversion(typeof(char), typeof(char)), Is.EqualTo(C.IdentityConversion)); + Assert.That(ImplicitConversion(typeof(string), typeof(string)), Is.EqualTo(C.IdentityConversion)); + Assert.That(ImplicitConversion(typeof(object), typeof(object)), Is.EqualTo(C.IdentityConversion)); + Assert.That(ImplicitConversion(typeof(bool), typeof(char)), Is.EqualTo(C.None)); - Assert.AreEqual(C.IdentityConversion, conversions.ImplicitConversion(SpecialType.Dynamic, SpecialType.Dynamic)); - Assert.AreEqual(C.IdentityConversion, conversions.ImplicitConversion(SpecialType.UnknownType, SpecialType.UnknownType)); - Assert.AreEqual(C.IdentityConversion, conversions.ImplicitConversion(SpecialType.NullType, SpecialType.NullType)); + Assert.That(conversions.ImplicitConversion(SpecialType.Dynamic, SpecialType.Dynamic), Is.EqualTo(C.IdentityConversion)); + Assert.That(conversions.ImplicitConversion(SpecialType.UnknownType, SpecialType.UnknownType), Is.EqualTo(C.IdentityConversion)); + Assert.That(conversions.ImplicitConversion(SpecialType.NullType, SpecialType.NullType), Is.EqualTo(C.IdentityConversion)); } [Test] public void DynamicIdentityConversions() { - Assert.AreEqual(C.IdentityConversion, ImplicitConversion(typeof(object), typeof(dynamic))); - Assert.AreEqual(C.IdentityConversion, ImplicitConversion(typeof(dynamic), typeof(object))); + Assert.That(ImplicitConversion(typeof(object), typeof(dynamic)), Is.EqualTo(C.IdentityConversion)); + Assert.That(ImplicitConversion(typeof(dynamic), typeof(object)), Is.EqualTo(C.IdentityConversion)); } [Test] public void ComplexDynamicIdentityConversions() { - Assert.AreEqual(C.IdentityConversion, ImplicitConversion(typeof(List), typeof(List))); - Assert.AreEqual(C.IdentityConversion, ImplicitConversion(typeof(List), typeof(List))); - Assert.AreEqual(C.None, ImplicitConversion(typeof(List), typeof(List))); - Assert.AreEqual(C.None, ImplicitConversion(typeof(List), typeof(List))); + Assert.That(ImplicitConversion(typeof(List), typeof(List)), Is.EqualTo(C.IdentityConversion)); + Assert.That(ImplicitConversion(typeof(List), typeof(List)), Is.EqualTo(C.IdentityConversion)); + Assert.That(ImplicitConversion(typeof(List), typeof(List)), Is.EqualTo(C.None)); + Assert.That(ImplicitConversion(typeof(List), typeof(List)), Is.EqualTo(C.None)); - Assert.AreEqual(C.IdentityConversion, ImplicitConversion(typeof(List[]>), typeof(List[]>))); - Assert.AreEqual(C.IdentityConversion, ImplicitConversion(typeof(List[]>), typeof(List[]>))); - Assert.AreEqual(C.None, ImplicitConversion(typeof(List[,]>), typeof(List[]>))); + Assert.That(ImplicitConversion(typeof(List[]>), typeof(List[]>)), Is.EqualTo(C.IdentityConversion)); + Assert.That(ImplicitConversion(typeof(List[]>), typeof(List[]>)), Is.EqualTo(C.IdentityConversion)); + Assert.That(ImplicitConversion(typeof(List[,]>), typeof(List[]>)), Is.EqualTo(C.None)); } [Test] @@ -105,40 +105,38 @@ public void TupleIdentityConversions() { var intType = compilation.FindType(typeof(int)); var stringType = compilation.FindType(typeof(string)); - Assert.AreEqual(C.IdentityConversion, conversions.ImplicitConversion( + Assert.That(conversions.ImplicitConversion( new TupleType(compilation, ImmutableArray.Create(intType, stringType), ImmutableArray.Create("a", "b")), - new TupleType(compilation, ImmutableArray.Create(intType, stringType), ImmutableArray.Create("a", "c")))); + new TupleType(compilation, ImmutableArray.Create(intType, stringType), ImmutableArray.Create("a", "c"))), Is.EqualTo(C.IdentityConversion)); - Assert.AreEqual(C.None, conversions.ImplicitConversion( + Assert.That(conversions.ImplicitConversion( new TupleType(compilation, ImmutableArray.Create(intType, stringType), ImmutableArray.Create("a", "b")), - new TupleType(compilation, ImmutableArray.Create(stringType, intType), ImmutableArray.Create("a", "b")))); + new TupleType(compilation, ImmutableArray.Create(stringType, intType), ImmutableArray.Create("a", "b"))), Is.EqualTo(C.None)); } [Test] public void TupleConversions() { - Assert.AreEqual( - C.TupleConversion(ImmutableArray.Create(C.ImplicitNumericConversion, C.ImplicitReferenceConversion)), - ImplicitConversion(typeof((int, string)), typeof((long, object)))); + Assert.That( + ImplicitConversion(typeof((int, string)), typeof((long, object))), Is.EqualTo(C.TupleConversion(ImmutableArray.Create(C.ImplicitNumericConversion, C.ImplicitReferenceConversion)))); - Assert.AreEqual( - C.TupleConversion(ImmutableArray.Create(C.ImplicitNumericConversion)), - ImplicitConversion(typeof(ValueTuple), typeof(ValueTuple))); + Assert.That( + ImplicitConversion(typeof(ValueTuple), typeof(ValueTuple)), Is.EqualTo(C.TupleConversion(ImmutableArray.Create(C.ImplicitNumericConversion)))); } [Test] public void PrimitiveConversions() { - Assert.AreEqual(C.ImplicitNumericConversion, ImplicitConversion(typeof(char), typeof(ushort))); - Assert.AreEqual(C.None, ImplicitConversion(typeof(byte), typeof(char))); - Assert.AreEqual(C.ImplicitNumericConversion, ImplicitConversion(typeof(int), typeof(long))); - Assert.AreEqual(C.None, ImplicitConversion(typeof(long), typeof(int))); - Assert.AreEqual(C.ImplicitNumericConversion, ImplicitConversion(typeof(int), typeof(float))); - Assert.AreEqual(C.None, ImplicitConversion(typeof(bool), typeof(float))); - Assert.AreEqual(C.ImplicitNumericConversion, ImplicitConversion(typeof(float), typeof(double))); - Assert.AreEqual(C.None, ImplicitConversion(typeof(float), typeof(decimal))); - Assert.AreEqual(C.ImplicitNumericConversion, ImplicitConversion(typeof(char), typeof(long))); - Assert.AreEqual(C.ImplicitNumericConversion, ImplicitConversion(typeof(uint), typeof(long))); + Assert.That(ImplicitConversion(typeof(char), typeof(ushort)), Is.EqualTo(C.ImplicitNumericConversion)); + Assert.That(ImplicitConversion(typeof(byte), typeof(char)), Is.EqualTo(C.None)); + Assert.That(ImplicitConversion(typeof(int), typeof(long)), Is.EqualTo(C.ImplicitNumericConversion)); + Assert.That(ImplicitConversion(typeof(long), typeof(int)), Is.EqualTo(C.None)); + Assert.That(ImplicitConversion(typeof(int), typeof(float)), Is.EqualTo(C.ImplicitNumericConversion)); + Assert.That(ImplicitConversion(typeof(bool), typeof(float)), Is.EqualTo(C.None)); + Assert.That(ImplicitConversion(typeof(float), typeof(double)), Is.EqualTo(C.ImplicitNumericConversion)); + Assert.That(ImplicitConversion(typeof(float), typeof(decimal)), Is.EqualTo(C.None)); + Assert.That(ImplicitConversion(typeof(char), typeof(long)), Is.EqualTo(C.ImplicitNumericConversion)); + Assert.That(ImplicitConversion(typeof(uint), typeof(long)), Is.EqualTo(C.ImplicitNumericConversion)); } [Test] @@ -147,64 +145,64 @@ public void EnumerationConversion() ResolveResult zero = new ConstantResolveResult(compilation.FindType(KnownTypeCode.Int32), 0); ResolveResult one = new ConstantResolveResult(compilation.FindType(KnownTypeCode.Int32), 1); C implicitEnumerationConversion = C.EnumerationConversion(true, false); - Assert.AreEqual(implicitEnumerationConversion, conversions.ImplicitConversion(zero, compilation.FindType(typeof(StringComparison)))); - Assert.AreEqual(C.None, conversions.ImplicitConversion(one, compilation.FindType(typeof(StringComparison)))); + Assert.That(conversions.ImplicitConversion(zero, compilation.FindType(typeof(StringComparison))), Is.EqualTo(implicitEnumerationConversion)); + Assert.That(conversions.ImplicitConversion(one, compilation.FindType(typeof(StringComparison))), Is.EqualTo(C.None)); } [Test] public void NullableConversions() { - Assert.AreEqual(C.ImplicitLiftedNumericConversion, ImplicitConversion(typeof(char), typeof(ushort?))); - Assert.AreEqual(C.None, ImplicitConversion(typeof(byte), typeof(char?))); - Assert.AreEqual(C.ImplicitLiftedNumericConversion, ImplicitConversion(typeof(int), typeof(long?))); - Assert.AreEqual(C.None, ImplicitConversion(typeof(long), typeof(int?))); - Assert.AreEqual(C.ImplicitLiftedNumericConversion, ImplicitConversion(typeof(int), typeof(float?))); - Assert.AreEqual(C.None, ImplicitConversion(typeof(bool), typeof(float?))); - Assert.AreEqual(C.ImplicitLiftedNumericConversion, ImplicitConversion(typeof(float), typeof(double?))); - Assert.AreEqual(C.None, ImplicitConversion(typeof(float), typeof(decimal?))); + Assert.That(ImplicitConversion(typeof(char), typeof(ushort?)), Is.EqualTo(C.ImplicitLiftedNumericConversion)); + Assert.That(ImplicitConversion(typeof(byte), typeof(char?)), Is.EqualTo(C.None)); + Assert.That(ImplicitConversion(typeof(int), typeof(long?)), Is.EqualTo(C.ImplicitLiftedNumericConversion)); + Assert.That(ImplicitConversion(typeof(long), typeof(int?)), Is.EqualTo(C.None)); + Assert.That(ImplicitConversion(typeof(int), typeof(float?)), Is.EqualTo(C.ImplicitLiftedNumericConversion)); + Assert.That(ImplicitConversion(typeof(bool), typeof(float?)), Is.EqualTo(C.None)); + Assert.That(ImplicitConversion(typeof(float), typeof(double?)), Is.EqualTo(C.ImplicitLiftedNumericConversion)); + Assert.That(ImplicitConversion(typeof(float), typeof(decimal?)), Is.EqualTo(C.None)); } [Test] public void NullableConversions2() { - Assert.AreEqual(C.ImplicitLiftedNumericConversion, ImplicitConversion(typeof(char?), typeof(ushort?))); - Assert.AreEqual(C.None, ImplicitConversion(typeof(byte?), typeof(char?))); - Assert.AreEqual(C.ImplicitLiftedNumericConversion, ImplicitConversion(typeof(int?), typeof(long?))); - Assert.AreEqual(C.None, ImplicitConversion(typeof(long?), typeof(int?))); - Assert.AreEqual(C.ImplicitLiftedNumericConversion, ImplicitConversion(typeof(int?), typeof(float?))); - Assert.AreEqual(C.None, ImplicitConversion(typeof(bool?), typeof(float?))); - Assert.AreEqual(C.ImplicitLiftedNumericConversion, ImplicitConversion(typeof(float?), typeof(double?))); - Assert.AreEqual(C.None, ImplicitConversion(typeof(float?), typeof(decimal?))); + Assert.That(ImplicitConversion(typeof(char?), typeof(ushort?)), Is.EqualTo(C.ImplicitLiftedNumericConversion)); + Assert.That(ImplicitConversion(typeof(byte?), typeof(char?)), Is.EqualTo(C.None)); + Assert.That(ImplicitConversion(typeof(int?), typeof(long?)), Is.EqualTo(C.ImplicitLiftedNumericConversion)); + Assert.That(ImplicitConversion(typeof(long?), typeof(int?)), Is.EqualTo(C.None)); + Assert.That(ImplicitConversion(typeof(int?), typeof(float?)), Is.EqualTo(C.ImplicitLiftedNumericConversion)); + Assert.That(ImplicitConversion(typeof(bool?), typeof(float?)), Is.EqualTo(C.None)); + Assert.That(ImplicitConversion(typeof(float?), typeof(double?)), Is.EqualTo(C.ImplicitLiftedNumericConversion)); + Assert.That(ImplicitConversion(typeof(float?), typeof(decimal?)), Is.EqualTo(C.None)); } [Test] public void NullLiteralConversions() { - Assert.AreEqual(C.NullLiteralConversion, ImplicitConversion(typeof(Null), typeof(int?))); - Assert.AreEqual(C.NullLiteralConversion, ImplicitConversion(typeof(Null), typeof(char?))); - Assert.AreEqual(C.None, ImplicitConversion(typeof(Null), typeof(int))); - Assert.AreEqual(C.NullLiteralConversion, ImplicitConversion(typeof(Null), typeof(object))); - Assert.AreEqual(C.NullLiteralConversion, ImplicitConversion(typeof(Null), typeof(dynamic))); - Assert.AreEqual(C.NullLiteralConversion, ImplicitConversion(typeof(Null), typeof(string))); - Assert.AreEqual(C.NullLiteralConversion, ImplicitConversion(typeof(Null), typeof(int[]))); + Assert.That(ImplicitConversion(typeof(Null), typeof(int?)), Is.EqualTo(C.NullLiteralConversion)); + Assert.That(ImplicitConversion(typeof(Null), typeof(char?)), Is.EqualTo(C.NullLiteralConversion)); + Assert.That(ImplicitConversion(typeof(Null), typeof(int)), Is.EqualTo(C.None)); + Assert.That(ImplicitConversion(typeof(Null), typeof(object)), Is.EqualTo(C.NullLiteralConversion)); + Assert.That(ImplicitConversion(typeof(Null), typeof(dynamic)), Is.EqualTo(C.NullLiteralConversion)); + Assert.That(ImplicitConversion(typeof(Null), typeof(string)), Is.EqualTo(C.NullLiteralConversion)); + Assert.That(ImplicitConversion(typeof(Null), typeof(int[])), Is.EqualTo(C.NullLiteralConversion)); } [Test] public void SimpleReferenceConversions() { - Assert.AreEqual(C.ImplicitReferenceConversion, ImplicitConversion(typeof(string), typeof(object))); - Assert.AreEqual(C.ImplicitReferenceConversion, ImplicitConversion(typeof(BitArray), typeof(ICollection))); - Assert.AreEqual(C.ImplicitReferenceConversion, ImplicitConversion(typeof(IList), typeof(IEnumerable))); - Assert.AreEqual(C.None, ImplicitConversion(typeof(object), typeof(string))); - Assert.AreEqual(C.None, ImplicitConversion(typeof(ICollection), typeof(BitArray))); - Assert.AreEqual(C.None, ImplicitConversion(typeof(IEnumerable), typeof(IList))); + Assert.That(ImplicitConversion(typeof(string), typeof(object)), Is.EqualTo(C.ImplicitReferenceConversion)); + Assert.That(ImplicitConversion(typeof(BitArray), typeof(ICollection)), Is.EqualTo(C.ImplicitReferenceConversion)); + Assert.That(ImplicitConversion(typeof(IList), typeof(IEnumerable)), Is.EqualTo(C.ImplicitReferenceConversion)); + Assert.That(ImplicitConversion(typeof(object), typeof(string)), Is.EqualTo(C.None)); + Assert.That(ImplicitConversion(typeof(ICollection), typeof(BitArray)), Is.EqualTo(C.None)); + Assert.That(ImplicitConversion(typeof(IEnumerable), typeof(IList)), Is.EqualTo(C.None)); } [Test] public void ConversionToDynamic() { - Assert.AreEqual(C.ImplicitReferenceConversion, ImplicitConversion(typeof(string), typeof(dynamic))); - Assert.AreEqual(C.BoxingConversion, ImplicitConversion(typeof(int), typeof(dynamic))); + Assert.That(ImplicitConversion(typeof(string), typeof(dynamic)), Is.EqualTo(C.ImplicitReferenceConversion)); + Assert.That(ImplicitConversion(typeof(int), typeof(dynamic)), Is.EqualTo(C.BoxingConversion)); } [Test] @@ -213,177 +211,164 @@ public void ConversionFromDynamic() // There is no conversion from the type 'dynamic' to other types (except the identity conversion to object). // Such conversions only exists from dynamic expression. // This is an important distinction for type inference (see TypeInferenceTests.IEnumerableCovarianceWithDynamic) - Assert.AreEqual(C.None, ImplicitConversion(typeof(dynamic), typeof(string))); - Assert.AreEqual(C.None, ImplicitConversion(typeof(dynamic), typeof(int))); + Assert.That(ImplicitConversion(typeof(dynamic), typeof(string)), Is.EqualTo(C.None)); + Assert.That(ImplicitConversion(typeof(dynamic), typeof(int)), Is.EqualTo(C.None)); var dynamicRR = new ResolveResult(SpecialType.Dynamic); - Assert.AreEqual(C.ImplicitDynamicConversion, conversions.ImplicitConversion(dynamicRR, compilation.FindType(typeof(string)))); - Assert.AreEqual(C.ImplicitDynamicConversion, conversions.ImplicitConversion(dynamicRR, compilation.FindType(typeof(int)))); + Assert.That(conversions.ImplicitConversion(dynamicRR, compilation.FindType(typeof(string))), Is.EqualTo(C.ImplicitDynamicConversion)); + Assert.That(conversions.ImplicitConversion(dynamicRR, compilation.FindType(typeof(int))), Is.EqualTo(C.ImplicitDynamicConversion)); } [Test] public void ParameterizedTypeConversions() { - Assert.AreEqual(C.ImplicitReferenceConversion, ImplicitConversion(typeof(List), typeof(ICollection))); - Assert.AreEqual(C.ImplicitReferenceConversion, ImplicitConversion(typeof(IList), typeof(ICollection))); - Assert.AreEqual(C.None, ImplicitConversion(typeof(List), typeof(ICollection))); - Assert.AreEqual(C.None, ImplicitConversion(typeof(IList), typeof(ICollection))); + Assert.That(ImplicitConversion(typeof(List), typeof(ICollection)), Is.EqualTo(C.ImplicitReferenceConversion)); + Assert.That(ImplicitConversion(typeof(IList), typeof(ICollection)), Is.EqualTo(C.ImplicitReferenceConversion)); + Assert.That(ImplicitConversion(typeof(List), typeof(ICollection)), Is.EqualTo(C.None)); + Assert.That(ImplicitConversion(typeof(IList), typeof(ICollection)), Is.EqualTo(C.None)); } [Test] public void ArrayConversions() { - Assert.AreEqual(C.ImplicitReferenceConversion, ImplicitConversion(typeof(string[]), typeof(object[]))); - Assert.AreEqual(C.ImplicitReferenceConversion, ImplicitConversion(typeof(string[,]), typeof(object[,]))); - Assert.AreEqual(C.None, ImplicitConversion(typeof(string[]), typeof(object[,]))); - Assert.AreEqual(C.None, ImplicitConversion(typeof(object[]), typeof(string[]))); + Assert.That(ImplicitConversion(typeof(string[]), typeof(object[])), Is.EqualTo(C.ImplicitReferenceConversion)); + Assert.That(ImplicitConversion(typeof(string[,]), typeof(object[,])), Is.EqualTo(C.ImplicitReferenceConversion)); + Assert.That(ImplicitConversion(typeof(string[]), typeof(object[,])), Is.EqualTo(C.None)); + Assert.That(ImplicitConversion(typeof(object[]), typeof(string[])), Is.EqualTo(C.None)); - Assert.AreEqual(C.ImplicitReferenceConversion, ImplicitConversion(typeof(string[]), typeof(IList))); - Assert.AreEqual(C.None, ImplicitConversion(typeof(string[,]), typeof(IList))); - Assert.AreEqual(C.ImplicitReferenceConversion, ImplicitConversion(typeof(string[]), typeof(IList))); + Assert.That(ImplicitConversion(typeof(string[]), typeof(IList)), Is.EqualTo(C.ImplicitReferenceConversion)); + Assert.That(ImplicitConversion(typeof(string[,]), typeof(IList)), Is.EqualTo(C.None)); + Assert.That(ImplicitConversion(typeof(string[]), typeof(IList)), Is.EqualTo(C.ImplicitReferenceConversion)); - Assert.AreEqual(C.ImplicitReferenceConversion, ImplicitConversion(typeof(string[]), typeof(Array))); - Assert.AreEqual(C.ImplicitReferenceConversion, ImplicitConversion(typeof(string[]), typeof(ICloneable))); - Assert.AreEqual(C.None, ImplicitConversion(typeof(Array), typeof(string[]))); - Assert.AreEqual(C.None, ImplicitConversion(typeof(object), typeof(object[]))); + Assert.That(ImplicitConversion(typeof(string[]), typeof(Array)), Is.EqualTo(C.ImplicitReferenceConversion)); + Assert.That(ImplicitConversion(typeof(string[]), typeof(ICloneable)), Is.EqualTo(C.ImplicitReferenceConversion)); + Assert.That(ImplicitConversion(typeof(Array), typeof(string[])), Is.EqualTo(C.None)); + Assert.That(ImplicitConversion(typeof(object), typeof(object[])), Is.EqualTo(C.None)); } [Test] public void VarianceConversions() { - Assert.AreEqual(C.ImplicitReferenceConversion, - ImplicitConversion(typeof(List), typeof(IEnumerable))); - Assert.AreEqual(C.None, - ImplicitConversion(typeof(List), typeof(IEnumerable))); - Assert.AreEqual(C.ImplicitReferenceConversion, - ImplicitConversion(typeof(IEnumerable), typeof(IEnumerable))); - Assert.AreEqual(C.None, - ImplicitConversion(typeof(ICollection), typeof(ICollection))); - - Assert.AreEqual(C.ImplicitReferenceConversion, - ImplicitConversion(typeof(Comparer), typeof(IComparer))); - Assert.AreEqual(C.ImplicitReferenceConversion, - ImplicitConversion(typeof(Comparer), typeof(IComparer))); - Assert.AreEqual(C.None, - ImplicitConversion(typeof(Comparer), typeof(Comparer))); - - Assert.AreEqual(C.None, - ImplicitConversion(typeof(List), typeof(IEnumerable))); - Assert.AreEqual(C.ImplicitReferenceConversion, - ImplicitConversion(typeof(IEnumerable), typeof(IEnumerable))); - - Assert.AreEqual(C.ImplicitReferenceConversion, - ImplicitConversion(typeof(Func), typeof(Func))); - Assert.AreEqual(C.ImplicitReferenceConversion, - ImplicitConversion(typeof(Func), typeof(Func))); - Assert.AreEqual(C.None, - ImplicitConversion(typeof(Func), typeof(Func))); - Assert.AreEqual(C.None, - ImplicitConversion(typeof(Func), typeof(Func))); + Assert.That(ImplicitConversion(typeof(List), typeof(IEnumerable)), Is.EqualTo(C.ImplicitReferenceConversion)); + Assert.That(ImplicitConversion(typeof(List), typeof(IEnumerable)), Is.EqualTo(C.None)); + Assert.That(ImplicitConversion(typeof(IEnumerable), typeof(IEnumerable)), Is.EqualTo(C.ImplicitReferenceConversion)); + Assert.That(ImplicitConversion(typeof(ICollection), typeof(ICollection)), Is.EqualTo(C.None)); + + Assert.That(ImplicitConversion(typeof(Comparer), typeof(IComparer)), Is.EqualTo(C.ImplicitReferenceConversion)); + Assert.That(ImplicitConversion(typeof(Comparer), typeof(IComparer)), Is.EqualTo(C.ImplicitReferenceConversion)); + Assert.That(ImplicitConversion(typeof(Comparer), typeof(Comparer)), Is.EqualTo(C.None)); + + Assert.That(ImplicitConversion(typeof(List), typeof(IEnumerable)), Is.EqualTo(C.None)); + Assert.That(ImplicitConversion(typeof(IEnumerable), typeof(IEnumerable)), Is.EqualTo(C.ImplicitReferenceConversion)); + + Assert.That(ImplicitConversion(typeof(Func), typeof(Func)), Is.EqualTo(C.ImplicitReferenceConversion)); + Assert.That(ImplicitConversion(typeof(Func), typeof(Func)), Is.EqualTo(C.ImplicitReferenceConversion)); + Assert.That(ImplicitConversion(typeof(Func), typeof(Func)), Is.EqualTo(C.None)); + Assert.That(ImplicitConversion(typeof(Func), typeof(Func)), Is.EqualTo(C.None)); } [Test] public void ImplicitPointerConversion() { - Assert.AreEqual(C.ImplicitPointerConversion, ImplicitConversion(typeof(Null), typeof(int*))); - Assert.AreEqual(C.ImplicitPointerConversion, ImplicitConversion(typeof(int*), typeof(void*))); + Assert.That(ImplicitConversion(typeof(Null), typeof(int*)), Is.EqualTo(C.ImplicitPointerConversion)); + Assert.That(ImplicitConversion(typeof(int*), typeof(void*)), Is.EqualTo(C.ImplicitPointerConversion)); } [Test] public void NoConversionFromPointerTypeToObject() { - Assert.AreEqual(C.None, ImplicitConversion(typeof(int*), typeof(object))); - Assert.AreEqual(C.None, ImplicitConversion(typeof(int*), typeof(dynamic))); + Assert.That(ImplicitConversion(typeof(int*), typeof(object)), Is.EqualTo(C.None)); + Assert.That(ImplicitConversion(typeof(int*), typeof(dynamic)), Is.EqualTo(C.None)); } [Test] public void ConversionToNInt() { // Test based on the table in https://github.com/dotnet/csharplang/blob/master/proposals/native-integers.md - Assert.AreEqual(C.UnboxingConversion, ExplicitConversion(typeof(object), typeof(nint))); - Assert.AreEqual(C.ExplicitPointerConversion, ExplicitConversion(typeof(void*), typeof(nint))); - Assert.AreEqual(C.ImplicitNumericConversion, ExplicitConversion(typeof(sbyte), typeof(nint))); - Assert.AreEqual(C.ImplicitNumericConversion, ExplicitConversion(typeof(byte), typeof(nint))); - Assert.AreEqual(C.ImplicitNumericConversion, ExplicitConversion(typeof(short), typeof(nint))); - Assert.AreEqual(C.ImplicitNumericConversion, ExplicitConversion(typeof(ushort), typeof(nint))); - Assert.AreEqual(C.ImplicitNumericConversion, ExplicitConversion(typeof(int), typeof(nint))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(uint), typeof(nint))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(long), typeof(nint))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(ulong), typeof(nint))); - Assert.AreEqual(C.ImplicitNumericConversion, ExplicitConversion(typeof(char), typeof(nint))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(float), typeof(nint))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(double), typeof(nint))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(decimal), typeof(nint))); - Assert.AreEqual(C.IdentityConversion, ExplicitConversion(typeof(IntPtr), typeof(nint))); - Assert.AreEqual(C.None, ExplicitConversion(typeof(UIntPtr), typeof(nint))); + Assert.That(ExplicitConversion(typeof(object), typeof(nint)), Is.EqualTo(C.UnboxingConversion)); + Assert.That(ExplicitConversion(typeof(void*), typeof(nint)), Is.EqualTo(C.ExplicitPointerConversion)); + Assert.That(ExplicitConversion(typeof(sbyte), typeof(nint)), Is.EqualTo(C.ImplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(byte), typeof(nint)), Is.EqualTo(C.ImplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(short), typeof(nint)), Is.EqualTo(C.ImplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(ushort), typeof(nint)), Is.EqualTo(C.ImplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(int), typeof(nint)), Is.EqualTo(C.ImplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(uint), typeof(nint)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(long), typeof(nint)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(ulong), typeof(nint)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(char), typeof(nint)), Is.EqualTo(C.ImplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(float), typeof(nint)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(double), typeof(nint)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(decimal), typeof(nint)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(IntPtr), typeof(nint)), Is.EqualTo(C.IdentityConversion)); + Assert.That(ExplicitConversion(typeof(UIntPtr), typeof(nint)), Is.EqualTo(C.None)); } [Test] public void ConversionToNUInt() { // Test based on the table in https://github.com/dotnet/csharplang/blob/master/proposals/native-integers.md - Assert.AreEqual(C.UnboxingConversion, ExplicitConversion(typeof(object), typeof(nuint))); - Assert.AreEqual(C.ExplicitPointerConversion, ExplicitConversion(typeof(void*), typeof(nuint))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(sbyte), typeof(nuint))); - Assert.AreEqual(C.ImplicitNumericConversion, ExplicitConversion(typeof(byte), typeof(nuint))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(short), typeof(nuint))); - Assert.AreEqual(C.ImplicitNumericConversion, ExplicitConversion(typeof(ushort), typeof(nuint))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(int), typeof(nuint))); - Assert.AreEqual(C.ImplicitNumericConversion, ExplicitConversion(typeof(uint), typeof(nuint))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(long), typeof(nuint))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(ulong), typeof(nuint))); - Assert.AreEqual(C.ImplicitNumericConversion, ExplicitConversion(typeof(char), typeof(nuint))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(float), typeof(nuint))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(double), typeof(nuint))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(decimal), typeof(nuint))); - Assert.AreEqual(C.None, ExplicitConversion(typeof(IntPtr), typeof(nuint))); - Assert.AreEqual(C.IdentityConversion, ExplicitConversion(typeof(UIntPtr), typeof(nuint))); + Assert.That(ExplicitConversion(typeof(object), typeof(nuint)), Is.EqualTo(C.UnboxingConversion)); + Assert.That(ExplicitConversion(typeof(void*), typeof(nuint)), Is.EqualTo(C.ExplicitPointerConversion)); + Assert.That(ExplicitConversion(typeof(sbyte), typeof(nuint)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(byte), typeof(nuint)), Is.EqualTo(C.ImplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(short), typeof(nuint)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(ushort), typeof(nuint)), Is.EqualTo(C.ImplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(int), typeof(nuint)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(uint), typeof(nuint)), Is.EqualTo(C.ImplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(long), typeof(nuint)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(ulong), typeof(nuint)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(char), typeof(nuint)), Is.EqualTo(C.ImplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(float), typeof(nuint)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(double), typeof(nuint)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(decimal), typeof(nuint)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(IntPtr), typeof(nuint)), Is.EqualTo(C.None)); + Assert.That(ExplicitConversion(typeof(UIntPtr), typeof(nuint)), Is.EqualTo(C.IdentityConversion)); } [Test] public void ConversionFromNInt() { // Test based on the table in https://github.com/dotnet/csharplang/blob/master/proposals/native-integers.md - Assert.AreEqual(C.BoxingConversion, ExplicitConversion(typeof(nint), typeof(object))); - Assert.AreEqual(C.ExplicitPointerConversion, ExplicitConversion(typeof(nint), typeof(void*))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(nint), typeof(nuint))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(nint), typeof(sbyte))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(nint), typeof(byte))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(nint), typeof(short))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(nint), typeof(ushort))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(nint), typeof(int))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(nint), typeof(uint))); - Assert.AreEqual(C.ImplicitNumericConversion, ExplicitConversion(typeof(nint), typeof(long))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(nint), typeof(ulong))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(nint), typeof(char))); - Assert.AreEqual(C.ImplicitNumericConversion, ExplicitConversion(typeof(nint), typeof(float))); - Assert.AreEqual(C.ImplicitNumericConversion, ExplicitConversion(typeof(nint), typeof(double))); - Assert.AreEqual(C.ImplicitNumericConversion, ExplicitConversion(typeof(nint), typeof(decimal))); - Assert.AreEqual(C.IdentityConversion, ExplicitConversion(typeof(nint), typeof(IntPtr))); - Assert.AreEqual(C.None, ExplicitConversion(typeof(nint), typeof(UIntPtr))); + Assert.That(ExplicitConversion(typeof(nint), typeof(object)), Is.EqualTo(C.BoxingConversion)); + Assert.That(ExplicitConversion(typeof(nint), typeof(void*)), Is.EqualTo(C.ExplicitPointerConversion)); + Assert.That(ExplicitConversion(typeof(nint), typeof(nuint)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(nint), typeof(sbyte)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(nint), typeof(byte)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(nint), typeof(short)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(nint), typeof(ushort)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(nint), typeof(int)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(nint), typeof(uint)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(nint), typeof(long)), Is.EqualTo(C.ImplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(nint), typeof(ulong)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(nint), typeof(char)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(nint), typeof(float)), Is.EqualTo(C.ImplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(nint), typeof(double)), Is.EqualTo(C.ImplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(nint), typeof(decimal)), Is.EqualTo(C.ImplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(nint), typeof(IntPtr)), Is.EqualTo(C.IdentityConversion)); + Assert.That(ExplicitConversion(typeof(nint), typeof(UIntPtr)), Is.EqualTo(C.None)); } [Test] public void ConversionFromNUInt() { // Test based on the table in https://github.com/dotnet/csharplang/blob/master/proposals/native-integers.md - Assert.AreEqual(C.BoxingConversion, ExplicitConversion(typeof(nuint), typeof(object))); - Assert.AreEqual(C.ExplicitPointerConversion, ExplicitConversion(typeof(nuint), typeof(void*))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(nuint), typeof(nint))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(nuint), typeof(sbyte))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(nuint), typeof(byte))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(nuint), typeof(short))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(nuint), typeof(ushort))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(nuint), typeof(int))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(nuint), typeof(uint))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(nuint), typeof(long))); - Assert.AreEqual(C.ImplicitNumericConversion, ExplicitConversion(typeof(nuint), typeof(ulong))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(nuint), typeof(char))); - Assert.AreEqual(C.ImplicitNumericConversion, ExplicitConversion(typeof(nuint), typeof(float))); - Assert.AreEqual(C.ImplicitNumericConversion, ExplicitConversion(typeof(nuint), typeof(double))); - Assert.AreEqual(C.ImplicitNumericConversion, ExplicitConversion(typeof(nuint), typeof(decimal))); - Assert.AreEqual(C.None, ExplicitConversion(typeof(nuint), typeof(IntPtr))); - Assert.AreEqual(C.IdentityConversion, ExplicitConversion(typeof(nuint), typeof(UIntPtr))); + Assert.That(ExplicitConversion(typeof(nuint), typeof(object)), Is.EqualTo(C.BoxingConversion)); + Assert.That(ExplicitConversion(typeof(nuint), typeof(void*)), Is.EqualTo(C.ExplicitPointerConversion)); + Assert.That(ExplicitConversion(typeof(nuint), typeof(nint)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(nuint), typeof(sbyte)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(nuint), typeof(byte)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(nuint), typeof(short)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(nuint), typeof(ushort)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(nuint), typeof(int)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(nuint), typeof(uint)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(nuint), typeof(long)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(nuint), typeof(ulong)), Is.EqualTo(C.ImplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(nuint), typeof(char)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(nuint), typeof(float)), Is.EqualTo(C.ImplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(nuint), typeof(double)), Is.EqualTo(C.ImplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(nuint), typeof(decimal)), Is.EqualTo(C.ImplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(nuint), typeof(IntPtr)), Is.EqualTo(C.None)); + Assert.That(ExplicitConversion(typeof(nuint), typeof(UIntPtr)), Is.EqualTo(C.IdentityConversion)); } @@ -391,29 +376,29 @@ public void ConversionFromNUInt() public void NIntEnumConversion() { var explicitEnumConversion = C.EnumerationConversion(isImplicit: false, isLifted: false); - Assert.AreEqual(explicitEnumConversion, ExplicitConversion(typeof(nint), typeof(StringComparison))); - Assert.AreEqual(explicitEnumConversion, ExplicitConversion(typeof(nuint), typeof(StringComparison))); - Assert.AreEqual(explicitEnumConversion, ExplicitConversion(typeof(StringComparison), typeof(nint))); - Assert.AreEqual(explicitEnumConversion, ExplicitConversion(typeof(StringComparison), typeof(nuint))); + Assert.That(ExplicitConversion(typeof(nint), typeof(StringComparison)), Is.EqualTo(explicitEnumConversion)); + Assert.That(ExplicitConversion(typeof(nuint), typeof(StringComparison)), Is.EqualTo(explicitEnumConversion)); + Assert.That(ExplicitConversion(typeof(StringComparison), typeof(nint)), Is.EqualTo(explicitEnumConversion)); + Assert.That(ExplicitConversion(typeof(StringComparison), typeof(nuint)), Is.EqualTo(explicitEnumConversion)); } [Test] public void IntegerLiteralToNIntConversions() { - Assert.IsTrue(IntegerLiteralConversion(0, typeof(nint))); - Assert.IsTrue(IntegerLiteralConversion(-1, typeof(nint))); - Assert.IsFalse(IntegerLiteralConversion(uint.MaxValue, typeof(nint))); - Assert.IsFalse(IntegerLiteralConversion(long.MaxValue, typeof(nint))); + Assert.That(IntegerLiteralConversion(0, typeof(nint))); + Assert.That(IntegerLiteralConversion(-1, typeof(nint))); + Assert.That(!IntegerLiteralConversion(uint.MaxValue, typeof(nint))); + Assert.That(!IntegerLiteralConversion(long.MaxValue, typeof(nint))); } [Test] public void IntegerLiteralToNUIntConversions() { - Assert.IsTrue(IntegerLiteralConversion(0, typeof(nuint))); - Assert.IsFalse(IntegerLiteralConversion(-1, typeof(nuint))); - Assert.IsTrue(IntegerLiteralConversion(uint.MaxValue, typeof(nuint))); - Assert.IsFalse(IntegerLiteralConversion(long.MaxValue, typeof(nuint))); + Assert.That(IntegerLiteralConversion(0, typeof(nuint))); + Assert.That(!IntegerLiteralConversion(-1, typeof(nuint))); + Assert.That(IntegerLiteralConversion(uint.MaxValue, typeof(nuint))); + Assert.That(!IntegerLiteralConversion(long.MaxValue, typeof(nuint))); } [Test] @@ -423,16 +408,16 @@ public void UnconstrainedTypeParameter() ITypeParameter t2 = new DefaultTypeParameter(compilation, SymbolKind.TypeDefinition, 1, "T2"); ITypeParameter tm = new DefaultTypeParameter(compilation, SymbolKind.Method, 0, "TM"); - Assert.AreEqual(C.None, conversions.ImplicitConversion(SpecialType.NullType, t)); - Assert.AreEqual(C.BoxingConversion, conversions.ImplicitConversion(t, compilation.FindType(KnownTypeCode.Object))); - Assert.AreEqual(C.BoxingConversion, conversions.ImplicitConversion(t, SpecialType.Dynamic)); - Assert.AreEqual(C.None, conversions.ImplicitConversion(t, compilation.FindType(typeof(ValueType)))); + Assert.That(conversions.ImplicitConversion(SpecialType.NullType, t), Is.EqualTo(C.None)); + Assert.That(conversions.ImplicitConversion(t, compilation.FindType(KnownTypeCode.Object)), Is.EqualTo(C.BoxingConversion)); + Assert.That(conversions.ImplicitConversion(t, SpecialType.Dynamic), Is.EqualTo(C.BoxingConversion)); + Assert.That(conversions.ImplicitConversion(t, compilation.FindType(typeof(ValueType))), Is.EqualTo(C.None)); - Assert.AreEqual(C.IdentityConversion, conversions.ImplicitConversion(t, t)); - Assert.AreEqual(C.None, conversions.ImplicitConversion(t2, t)); - Assert.AreEqual(C.None, conversions.ImplicitConversion(t, t2)); - Assert.AreEqual(C.None, conversions.ImplicitConversion(t, tm)); - Assert.AreEqual(C.None, conversions.ImplicitConversion(tm, t)); + Assert.That(conversions.ImplicitConversion(t, t), Is.EqualTo(C.IdentityConversion)); + Assert.That(conversions.ImplicitConversion(t2, t), Is.EqualTo(C.None)); + Assert.That(conversions.ImplicitConversion(t, t2), Is.EqualTo(C.None)); + Assert.That(conversions.ImplicitConversion(t, tm), Is.EqualTo(C.None)); + Assert.That(conversions.ImplicitConversion(tm, t), Is.EqualTo(C.None)); } [Test] @@ -440,10 +425,10 @@ public void TypeParameterWithReferenceTypeConstraint() { ITypeParameter t = new DefaultTypeParameter(compilation, SymbolKind.TypeDefinition, 0, "T", hasReferenceTypeConstraint: true); - Assert.AreEqual(C.NullLiteralConversion, conversions.ImplicitConversion(SpecialType.NullType, t)); - Assert.AreEqual(C.ImplicitReferenceConversion, conversions.ImplicitConversion(t, compilation.FindType(KnownTypeCode.Object))); - Assert.AreEqual(C.ImplicitReferenceConversion, conversions.ImplicitConversion(t, SpecialType.Dynamic)); - Assert.AreEqual(C.None, conversions.ImplicitConversion(t, compilation.FindType(typeof(ValueType)))); + Assert.That(conversions.ImplicitConversion(SpecialType.NullType, t), Is.EqualTo(C.NullLiteralConversion)); + Assert.That(conversions.ImplicitConversion(t, compilation.FindType(KnownTypeCode.Object)), Is.EqualTo(C.ImplicitReferenceConversion)); + Assert.That(conversions.ImplicitConversion(t, SpecialType.Dynamic), Is.EqualTo(C.ImplicitReferenceConversion)); + Assert.That(conversions.ImplicitConversion(t, compilation.FindType(typeof(ValueType))), Is.EqualTo(C.None)); } [Test] @@ -451,10 +436,10 @@ public void TypeParameterWithValueTypeConstraint() { ITypeParameter t = new DefaultTypeParameter(compilation, SymbolKind.TypeDefinition, 0, "T", hasValueTypeConstraint: true); - Assert.AreEqual(C.None, conversions.ImplicitConversion(SpecialType.NullType, t)); - Assert.AreEqual(C.BoxingConversion, conversions.ImplicitConversion(t, compilation.FindType(KnownTypeCode.Object))); - Assert.AreEqual(C.BoxingConversion, conversions.ImplicitConversion(t, SpecialType.Dynamic)); - Assert.AreEqual(C.BoxingConversion, conversions.ImplicitConversion(t, compilation.FindType(typeof(ValueType)))); + Assert.That(conversions.ImplicitConversion(SpecialType.NullType, t), Is.EqualTo(C.None)); + Assert.That(conversions.ImplicitConversion(t, compilation.FindType(KnownTypeCode.Object)), Is.EqualTo(C.BoxingConversion)); + Assert.That(conversions.ImplicitConversion(t, SpecialType.Dynamic), Is.EqualTo(C.BoxingConversion)); + Assert.That(conversions.ImplicitConversion(t, compilation.FindType(typeof(ValueType))), Is.EqualTo(C.BoxingConversion)); } [Test] @@ -463,20 +448,14 @@ public void TypeParameterWithClassConstraint() ITypeParameter t = new DefaultTypeParameter(compilation, SymbolKind.TypeDefinition, 0, "T", constraints: new[] { compilation.FindType(typeof(StringComparer)) }); - Assert.AreEqual(C.NullLiteralConversion, - conversions.ImplicitConversion(SpecialType.NullType, t)); - Assert.AreEqual(C.ImplicitReferenceConversion, - conversions.ImplicitConversion(t, compilation.FindType(KnownTypeCode.Object))); - Assert.AreEqual(C.ImplicitReferenceConversion, - conversions.ImplicitConversion(t, SpecialType.Dynamic)); - Assert.AreEqual(C.None, conversions.ImplicitConversion(t, compilation.FindType(typeof(ValueType)))); - Assert.AreEqual(C.ImplicitReferenceConversion, - conversions.ImplicitConversion(t, compilation.FindType(typeof(StringComparer)))); - Assert.AreEqual(C.ImplicitReferenceConversion, - conversions.ImplicitConversion(t, compilation.FindType(typeof(IComparer)))); - Assert.AreEqual(C.None, conversions.ImplicitConversion(t, compilation.FindType(typeof(IComparer)))); - Assert.AreEqual(C.ImplicitReferenceConversion, - conversions.ImplicitConversion(t, compilation.FindType(typeof(IComparer)))); + Assert.That(conversions.ImplicitConversion(SpecialType.NullType, t), Is.EqualTo(C.NullLiteralConversion)); + Assert.That(conversions.ImplicitConversion(t, compilation.FindType(KnownTypeCode.Object)), Is.EqualTo(C.ImplicitReferenceConversion)); + Assert.That(conversions.ImplicitConversion(t, SpecialType.Dynamic), Is.EqualTo(C.ImplicitReferenceConversion)); + Assert.That(conversions.ImplicitConversion(t, compilation.FindType(typeof(ValueType))), Is.EqualTo(C.None)); + Assert.That(conversions.ImplicitConversion(t, compilation.FindType(typeof(StringComparer))), Is.EqualTo(C.ImplicitReferenceConversion)); + Assert.That(conversions.ImplicitConversion(t, compilation.FindType(typeof(IComparer))), Is.EqualTo(C.ImplicitReferenceConversion)); + Assert.That(conversions.ImplicitConversion(t, compilation.FindType(typeof(IComparer))), Is.EqualTo(C.None)); + Assert.That(conversions.ImplicitConversion(t, compilation.FindType(typeof(IComparer))), Is.EqualTo(C.ImplicitReferenceConversion)); } [Test] @@ -485,26 +464,22 @@ public void TypeParameterWithInterfaceConstraint() ITypeParameter t = new DefaultTypeParameter(compilation, SymbolKind.TypeDefinition, 0, "T", constraints: new[] { compilation.FindType(typeof(IList)) }); - Assert.AreEqual(C.None, conversions.ImplicitConversion(SpecialType.NullType, t)); - Assert.AreEqual(C.BoxingConversion, - conversions.ImplicitConversion(t, compilation.FindType(KnownTypeCode.Object))); - Assert.AreEqual(C.BoxingConversion, - conversions.ImplicitConversion(t, SpecialType.Dynamic)); - Assert.AreEqual(C.None, conversions.ImplicitConversion(t, compilation.FindType(typeof(ValueType)))); - Assert.AreEqual(C.BoxingConversion, - conversions.ImplicitConversion(t, compilation.FindType(typeof(IList)))); - Assert.AreEqual(C.BoxingConversion, - conversions.ImplicitConversion(t, compilation.FindType(typeof(IEnumerable)))); + Assert.That(conversions.ImplicitConversion(SpecialType.NullType, t), Is.EqualTo(C.None)); + Assert.That(conversions.ImplicitConversion(t, compilation.FindType(KnownTypeCode.Object)), Is.EqualTo(C.BoxingConversion)); + Assert.That(conversions.ImplicitConversion(t, SpecialType.Dynamic), Is.EqualTo(C.BoxingConversion)); + Assert.That(conversions.ImplicitConversion(t, compilation.FindType(typeof(ValueType))), Is.EqualTo(C.None)); + Assert.That(conversions.ImplicitConversion(t, compilation.FindType(typeof(IList))), Is.EqualTo(C.BoxingConversion)); + Assert.That(conversions.ImplicitConversion(t, compilation.FindType(typeof(IEnumerable))), Is.EqualTo(C.BoxingConversion)); } [Test] public void UserDefinedImplicitConversion() { Conversion c = ImplicitConversion(typeof(DateTime), typeof(DateTimeOffset)); - Assert.IsTrue(c.IsImplicit && c.IsUserDefined); - Assert.AreEqual("System.DateTimeOffset.op_Implicit", c.Method.FullName); + Assert.That(c.IsImplicit && c.IsUserDefined); + Assert.That(c.Method.FullName, Is.EqualTo("System.DateTimeOffset.op_Implicit")); - Assert.AreEqual(C.None, ImplicitConversion(typeof(DateTimeOffset), typeof(DateTime))); + Assert.That(ImplicitConversion(typeof(DateTimeOffset), typeof(DateTime)), Is.EqualTo(C.None)); } [Test] @@ -512,14 +487,14 @@ public void UserDefinedImplicitNullableConversion() { // User-defined conversion followed by nullable conversion Conversion c = ImplicitConversion(typeof(DateTime), typeof(DateTimeOffset?)); - Assert.IsTrue(c.IsValid && c.IsUserDefined); - Assert.IsFalse(c.IsLifted); + Assert.That(c.IsValid && c.IsUserDefined); + Assert.That(!c.IsLifted); // Lifted user-defined conversion c = ImplicitConversion(typeof(DateTime?), typeof(DateTimeOffset?)); - Assert.IsTrue(c.IsValid && c.IsUserDefined && c.IsLifted); + Assert.That(c.IsValid && c.IsUserDefined && c.IsLifted); // User-defined conversion doesn't drop the nullability c = ImplicitConversion(typeof(DateTime?), typeof(DateTimeOffset)); - Assert.IsFalse(c.IsValid); + Assert.That(!c.IsValid); } bool IntegerLiteralConversion(object value, Type to) @@ -533,71 +508,71 @@ bool IntegerLiteralConversion(object value, Type to) [Test] public void IntegerLiteralToEnumConversions() { - Assert.IsTrue(IntegerLiteralConversion(0, typeof(LoaderOptimization))); - Assert.IsTrue(IntegerLiteralConversion(0L, typeof(LoaderOptimization))); - Assert.IsTrue(IntegerLiteralConversion(0, typeof(LoaderOptimization?))); - Assert.IsFalse(IntegerLiteralConversion(0, typeof(string))); - Assert.IsFalse(IntegerLiteralConversion(1, typeof(LoaderOptimization))); + Assert.That(IntegerLiteralConversion(0, typeof(LoaderOptimization))); + Assert.That(IntegerLiteralConversion(0L, typeof(LoaderOptimization))); + Assert.That(IntegerLiteralConversion(0, typeof(LoaderOptimization?))); + Assert.That(!IntegerLiteralConversion(0, typeof(string))); + Assert.That(!IntegerLiteralConversion(1, typeof(LoaderOptimization))); } [Test] public void ImplicitConstantExpressionConversion() { - Assert.IsTrue(IntegerLiteralConversion(0, typeof(int))); - Assert.IsTrue(IntegerLiteralConversion(0, typeof(ushort))); - Assert.IsTrue(IntegerLiteralConversion(0, typeof(sbyte))); + Assert.That(IntegerLiteralConversion(0, typeof(int))); + Assert.That(IntegerLiteralConversion(0, typeof(ushort))); + Assert.That(IntegerLiteralConversion(0, typeof(sbyte))); - Assert.IsTrue(IntegerLiteralConversion(-1, typeof(int))); - Assert.IsFalse(IntegerLiteralConversion(-1, typeof(ushort))); - Assert.IsTrue(IntegerLiteralConversion(-1, typeof(sbyte))); + Assert.That(IntegerLiteralConversion(-1, typeof(int))); + Assert.That(!IntegerLiteralConversion(-1, typeof(ushort))); + Assert.That(IntegerLiteralConversion(-1, typeof(sbyte))); - Assert.IsTrue(IntegerLiteralConversion(200, typeof(int))); - Assert.IsTrue(IntegerLiteralConversion(200, typeof(ushort))); - Assert.IsFalse(IntegerLiteralConversion(200, typeof(sbyte))); + Assert.That(IntegerLiteralConversion(200, typeof(int))); + Assert.That(IntegerLiteralConversion(200, typeof(ushort))); + Assert.That(!IntegerLiteralConversion(200, typeof(sbyte))); } [Test] public void ImplicitLongConstantExpressionConversion() { - Assert.IsFalse(IntegerLiteralConversion(0L, typeof(int))); - Assert.IsFalse(IntegerLiteralConversion(0L, typeof(short))); - Assert.IsTrue(IntegerLiteralConversion(0L, typeof(long))); - Assert.IsTrue(IntegerLiteralConversion(0L, typeof(ulong))); + Assert.That(!IntegerLiteralConversion(0L, typeof(int))); + Assert.That(!IntegerLiteralConversion(0L, typeof(short))); + Assert.That(IntegerLiteralConversion(0L, typeof(long))); + Assert.That(IntegerLiteralConversion(0L, typeof(ulong))); - Assert.IsTrue(IntegerLiteralConversion(-1L, typeof(long))); - Assert.IsFalse(IntegerLiteralConversion(-1L, typeof(ulong))); + Assert.That(IntegerLiteralConversion(-1L, typeof(long))); + Assert.That(!IntegerLiteralConversion(-1L, typeof(ulong))); } [Test] public void ImplicitConstantExpressionConversionToNullable() { - Assert.IsTrue(IntegerLiteralConversion(0, typeof(uint?))); - Assert.IsTrue(IntegerLiteralConversion(0, typeof(short?))); - Assert.IsTrue(IntegerLiteralConversion(0, typeof(byte?))); + Assert.That(IntegerLiteralConversion(0, typeof(uint?))); + Assert.That(IntegerLiteralConversion(0, typeof(short?))); + Assert.That(IntegerLiteralConversion(0, typeof(byte?))); - Assert.IsFalse(IntegerLiteralConversion(-1, typeof(uint?))); - Assert.IsTrue(IntegerLiteralConversion(-1, typeof(short?))); - Assert.IsFalse(IntegerLiteralConversion(-1, typeof(byte?))); + Assert.That(!IntegerLiteralConversion(-1, typeof(uint?))); + Assert.That(IntegerLiteralConversion(-1, typeof(short?))); + Assert.That(!IntegerLiteralConversion(-1, typeof(byte?))); - Assert.IsTrue(IntegerLiteralConversion(200, typeof(uint?))); - Assert.IsTrue(IntegerLiteralConversion(200, typeof(short?))); - Assert.IsTrue(IntegerLiteralConversion(200, typeof(byte?))); + Assert.That(IntegerLiteralConversion(200, typeof(uint?))); + Assert.That(IntegerLiteralConversion(200, typeof(short?))); + Assert.That(IntegerLiteralConversion(200, typeof(byte?))); - Assert.IsFalse(IntegerLiteralConversion(0L, typeof(uint?))); - Assert.IsTrue(IntegerLiteralConversion(0L, typeof(long?))); - Assert.IsTrue(IntegerLiteralConversion(0L, typeof(ulong?))); + Assert.That(!IntegerLiteralConversion(0L, typeof(uint?))); + Assert.That(IntegerLiteralConversion(0L, typeof(long?))); + Assert.That(IntegerLiteralConversion(0L, typeof(ulong?))); - Assert.IsTrue(IntegerLiteralConversion(-1L, typeof(long?))); - Assert.IsFalse(IntegerLiteralConversion(-1L, typeof(ulong?))); + Assert.That(IntegerLiteralConversion(-1L, typeof(long?))); + Assert.That(!IntegerLiteralConversion(-1L, typeof(ulong?))); } [Test] public void ImplicitConstantExpressionConversionNumberInterfaces() { - Assert.IsTrue(IntegerLiteralConversion(0, typeof(IFormattable))); - Assert.IsTrue(IntegerLiteralConversion(0, typeof(IComparable))); - Assert.IsFalse(IntegerLiteralConversion(0, typeof(IComparable))); - Assert.IsFalse(IntegerLiteralConversion(0, typeof(IComparable))); + Assert.That(IntegerLiteralConversion(0, typeof(IFormattable))); + Assert.That(IntegerLiteralConversion(0, typeof(IComparable))); + Assert.That(!IntegerLiteralConversion(0, typeof(IComparable))); + Assert.That(!IntegerLiteralConversion(0, typeof(IComparable))); } int BetterConversion(Type s, Type t1, Type t2) @@ -620,39 +595,39 @@ int BetterConversion(object value, Type t1, Type t2) [Test] public void BetterConversion() { - Assert.AreEqual(1, BetterConversion(typeof(string), typeof(string), typeof(object))); - Assert.AreEqual(2, BetterConversion(typeof(string), typeof(object), typeof(IComparable))); - Assert.AreEqual(0, BetterConversion(typeof(string), typeof(IEnumerable), typeof(IComparable))); + Assert.That(BetterConversion(typeof(string), typeof(string), typeof(object)), Is.EqualTo(1)); + Assert.That(BetterConversion(typeof(string), typeof(object), typeof(IComparable)), Is.EqualTo(2)); + Assert.That(BetterConversion(typeof(string), typeof(IEnumerable), typeof(IComparable)), Is.EqualTo(0)); } [Test] public void BetterPrimitiveConversion() { - Assert.AreEqual(1, BetterConversion(typeof(short), typeof(int), typeof(long))); - Assert.AreEqual(1, BetterConversion(typeof(short), typeof(int), typeof(uint))); - Assert.AreEqual(2, BetterConversion(typeof(ushort), typeof(uint), typeof(int))); - Assert.AreEqual(1, BetterConversion(typeof(char), typeof(short), typeof(int))); - Assert.AreEqual(1, BetterConversion(typeof(char), typeof(ushort), typeof(int))); - Assert.AreEqual(1, BetterConversion(typeof(sbyte), typeof(long), typeof(ulong))); - Assert.AreEqual(2, BetterConversion(typeof(byte), typeof(ushort), typeof(short))); + Assert.That(BetterConversion(typeof(short), typeof(int), typeof(long)), Is.EqualTo(1)); + Assert.That(BetterConversion(typeof(short), typeof(int), typeof(uint)), Is.EqualTo(1)); + Assert.That(BetterConversion(typeof(ushort), typeof(uint), typeof(int)), Is.EqualTo(2)); + Assert.That(BetterConversion(typeof(char), typeof(short), typeof(int)), Is.EqualTo(1)); + Assert.That(BetterConversion(typeof(char), typeof(ushort), typeof(int)), Is.EqualTo(1)); + Assert.That(BetterConversion(typeof(sbyte), typeof(long), typeof(ulong)), Is.EqualTo(1)); + Assert.That(BetterConversion(typeof(byte), typeof(ushort), typeof(short)), Is.EqualTo(2)); - Assert.AreEqual(1, BetterConversion(1, typeof(sbyte), typeof(byte))); - Assert.AreEqual(2, BetterConversion(1, typeof(ushort), typeof(sbyte))); + Assert.That(BetterConversion(1, typeof(sbyte), typeof(byte)), Is.EqualTo(1)); + Assert.That(BetterConversion(1, typeof(ushort), typeof(sbyte)), Is.EqualTo(2)); } [Test] public void BetterNullableConversion() { - Assert.AreEqual(0, BetterConversion(typeof(byte), typeof(int), typeof(uint?))); - Assert.AreEqual(0, BetterConversion(typeof(byte?), typeof(int?), typeof(uint?))); - Assert.AreEqual(1, BetterConversion(typeof(byte), typeof(ushort?), typeof(uint?))); - Assert.AreEqual(2, BetterConversion(typeof(byte?), typeof(ulong?), typeof(uint?))); - Assert.AreEqual(0, BetterConversion(typeof(byte), typeof(ushort?), typeof(uint))); - Assert.AreEqual(0, BetterConversion(typeof(byte), typeof(ushort?), typeof(int))); - Assert.AreEqual(2, BetterConversion(typeof(byte), typeof(ulong?), typeof(uint))); - Assert.AreEqual(0, BetterConversion(typeof(byte), typeof(ulong?), typeof(int))); - Assert.AreEqual(2, BetterConversion(typeof(ushort?), typeof(long?), typeof(int?))); - Assert.AreEqual(0, BetterConversion(typeof(sbyte), typeof(int?), typeof(uint?))); + Assert.That(BetterConversion(typeof(byte), typeof(int), typeof(uint?)), Is.EqualTo(0)); + Assert.That(BetterConversion(typeof(byte?), typeof(int?), typeof(uint?)), Is.EqualTo(0)); + Assert.That(BetterConversion(typeof(byte), typeof(ushort?), typeof(uint?)), Is.EqualTo(1)); + Assert.That(BetterConversion(typeof(byte?), typeof(ulong?), typeof(uint?)), Is.EqualTo(2)); + Assert.That(BetterConversion(typeof(byte), typeof(ushort?), typeof(uint)), Is.EqualTo(0)); + Assert.That(BetterConversion(typeof(byte), typeof(ushort?), typeof(int)), Is.EqualTo(0)); + Assert.That(BetterConversion(typeof(byte), typeof(ulong?), typeof(uint)), Is.EqualTo(2)); + Assert.That(BetterConversion(typeof(byte), typeof(ulong?), typeof(int)), Is.EqualTo(0)); + Assert.That(BetterConversion(typeof(ushort?), typeof(long?), typeof(int?)), Is.EqualTo(2)); + Assert.That(BetterConversion(typeof(sbyte), typeof(int?), typeof(uint?)), Is.EqualTo(0)); } /* TODO: we should probably revive these tests somehow @@ -678,7 +653,7 @@ public void ExpansiveInheritance() IType type1 = new ParameterizedType(resolvedB, new[] { compilation.FindType(KnownTypeCode.Double) }); IType type2 = new ParameterizedType(resolvedA, new[] { new ParameterizedType(resolvedB, new[] { compilation.FindType(KnownTypeCode.String) }) }); - Assert.IsFalse(conversions.ImplicitConversion(type1, type2).IsValid); + Assert.That(!conversions.ImplicitConversion(type1, type2).IsValid); } [Test] @@ -776,9 +751,9 @@ class Test { public static void M() {} }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); - Assert.IsTrue(c.IsMethodGroupConversion); - Assert.IsFalse(c.DelegateCapturesFirstArgument); + Assert.That(c.IsValid); + Assert.That(c.IsMethodGroupConversion); + Assert.That(!c.DelegateCapturesFirstArgument); Assert.IsNotNull(c.Method); } @@ -794,9 +769,9 @@ public void M() { } }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); - Assert.IsTrue(c.IsMethodGroupConversion); - Assert.IsTrue(c.DelegateCapturesFirstArgument); + Assert.That(c.IsValid); + Assert.That(c.IsMethodGroupConversion); + Assert.That(c.DelegateCapturesFirstArgument); Assert.IsNotNull(c.Method); } @@ -810,8 +785,8 @@ class Test { public static object M(int argument) {} }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); - Assert.IsTrue(c.IsMethodGroupConversion); + Assert.That(c.IsValid); + Assert.That(c.IsMethodGroupConversion); } [Test] @@ -824,8 +799,8 @@ class Test { public static int M(int argument) {} }"; var c = GetConversion(program); - Assert.IsFalse(c.IsValid); - Assert.IsTrue(c.IsMethodGroupConversion); + Assert.That(!c.IsValid); + Assert.That(c.IsMethodGroupConversion); } [Test] @@ -838,8 +813,8 @@ class Test { public static string M(int argument) {} }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); - Assert.IsTrue(c.IsMethodGroupConversion); + Assert.That(c.IsValid); + Assert.That(c.IsMethodGroupConversion); } [Test] @@ -852,8 +827,8 @@ class Test { public static void M(ref object o) {} }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); - Assert.IsTrue(c.IsMethodGroupConversion); + Assert.That(c.IsValid); + Assert.That(c.IsMethodGroupConversion); } [Test] @@ -866,8 +841,8 @@ class Test { public static void M(ref dynamic o) {} }"; var c = GetConversion(program); - Assert.IsFalse(c.IsValid); - Assert.IsTrue(c.IsMethodGroupConversion); + Assert.That(!c.IsValid); + Assert.That(c.IsMethodGroupConversion); } [Test] @@ -880,7 +855,7 @@ class Test { public static void M(out object o) {} }"; var c = GetConversion(program); - Assert.IsFalse(c.IsValid); + Assert.That(!c.IsValid); } [Test] @@ -893,7 +868,7 @@ class Test { public static void M(object o) {} }"; var c = GetConversion(program); - Assert.IsFalse(c.IsValid); + Assert.That(!c.IsValid); } [Test] @@ -906,7 +881,7 @@ class Test { public static void M(out object o) {} }"; var c = GetConversion(program); - Assert.IsFalse(c.IsValid); + Assert.That(!c.IsValid); } [Test] @@ -919,8 +894,8 @@ class Test { public static void M(object o) {} }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); - Assert.IsTrue(c.IsMethodGroupConversion); + Assert.That(c.IsValid); + Assert.That(c.IsMethodGroupConversion); } [Test] @@ -933,8 +908,8 @@ class Test { public static void M(dynamic o) {} }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); - Assert.IsTrue(c.IsMethodGroupConversion); + Assert.That(c.IsValid); + Assert.That(c.IsMethodGroupConversion); } [Test] @@ -947,8 +922,8 @@ class Test { public static void M(object o) {} }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); - Assert.IsTrue(c.IsMethodGroupConversion); + Assert.That(c.IsValid); + Assert.That(c.IsMethodGroupConversion); } @@ -963,7 +938,7 @@ public static void M(dynamic o) {} }"; var c = GetConversion(program); //Assert.IsFrue(c.IsValid); - Assert.IsTrue(c.IsMethodGroupConversion); + Assert.That(c.IsMethodGroupConversion); } [Test] @@ -977,8 +952,8 @@ static void M(object x) {} static void M(string x = null) {} }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); - Assert.IsTrue(c.IsMethodGroupConversion); + Assert.That(c.IsValid); + Assert.That(c.IsMethodGroupConversion); Assert.AreEqual("System.String", c.Method.Parameters.Single().Type.FullName); } @@ -993,8 +968,8 @@ static void M(object x) {} static void M(string x, string y = null) {} }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); - Assert.IsTrue(c.IsMethodGroupConversion); + Assert.That(c.IsValid); + Assert.That(c.IsMethodGroupConversion); Assert.AreEqual("System.Object", c.Method.Parameters.Single().Type.FullName); } @@ -1009,8 +984,8 @@ static void M(object x) {} static void M(params string[] x) {} }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); - Assert.IsTrue(c.IsMethodGroupConversion); + Assert.That(c.IsValid); + Assert.That(c.IsMethodGroupConversion); Assert.AreEqual("System.Object", c.Method.Parameters.Single().Type.FullName); } @@ -1029,9 +1004,9 @@ void F() { } }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); - Assert.IsTrue(c.IsMethodGroupConversion); - Assert.IsTrue(c.DelegateCapturesFirstArgument); + Assert.That(c.IsValid); + Assert.That(c.IsMethodGroupConversion); + Assert.That(c.DelegateCapturesFirstArgument); } [Test] @@ -1048,9 +1023,9 @@ void F() { } }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); - Assert.IsTrue(c.IsMethodGroupConversion); - Assert.IsFalse(c.DelegateCapturesFirstArgument); + Assert.That(c.IsValid); + Assert.That(c.IsMethodGroupConversion); + Assert.That(!c.DelegateCapturesFirstArgument); } [Test] @@ -1064,7 +1039,7 @@ public void M() { } }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); + Assert.That(c.IsValid); } [Test] @@ -1079,7 +1054,7 @@ public void M() { } }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); + Assert.That(c.IsValid); } [Test] @@ -1093,7 +1068,7 @@ public void M() { } }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); + Assert.That(c.IsValid); } [Test] @@ -1107,7 +1082,7 @@ public void M() { } }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); + Assert.That(c.IsValid); } [Test] @@ -1122,7 +1097,7 @@ public void M() { } }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); + Assert.That(c.IsValid); } [Test] @@ -1136,7 +1111,7 @@ public void M() { } }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); + Assert.That(c.IsValid); } [Test] @@ -1152,8 +1127,8 @@ static void M() { } }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); - Assert.IsTrue(c.IsUserDefined); + Assert.That(c.IsValid); + Assert.That(c.IsUserDefined); } [Test] @@ -1170,8 +1145,8 @@ static void M() { } }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); - Assert.IsTrue(c.IsUserDefined); + Assert.That(c.IsValid); + Assert.That(c.IsUserDefined); } @@ -1189,9 +1164,9 @@ static void M(S? s) { } }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); - Assert.IsTrue(c.IsUserDefined); - Assert.IsTrue(c.IsLifted); + Assert.That(c.IsValid); + Assert.That(c.IsUserDefined); + Assert.That(c.IsLifted); } [Test] @@ -1208,8 +1183,8 @@ public void M() { } }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); - Assert.IsTrue(c.IsUserDefined); + Assert.That(c.IsValid); + Assert.That(c.IsUserDefined); Assert.AreEqual("i", c.Method.Parameters[0].Name); } @@ -1227,8 +1202,8 @@ public void M() { } }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); - Assert.IsTrue(c.IsUserDefined); + Assert.That(c.IsValid); + Assert.That(c.IsUserDefined); Assert.AreEqual("ui", c.Method.Parameters[0].Name); } @@ -1246,7 +1221,7 @@ public void M() { } }"; var c = GetConversion(program); - Assert.IsFalse(c.IsValid); + Assert.That(!c.IsValid); } [Test] @@ -1263,8 +1238,8 @@ public void M() { } }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); - Assert.IsTrue(c.IsUserDefined); + Assert.That(c.IsValid); + Assert.That(c.IsUserDefined); Assert.AreEqual("i", c.Method.Parameters[0].Name); } @@ -1282,8 +1257,8 @@ public void M() { } }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); - Assert.IsTrue(c.IsUserDefined); + Assert.That(c.IsValid); + Assert.That(c.IsUserDefined); Assert.AreEqual("us", c.Method.Parameters[0].Name); } @@ -1301,7 +1276,7 @@ public void M() { } }"; var c = GetConversion(program); - Assert.IsFalse(c.IsValid); + Assert.That(!c.IsValid); } [Test] @@ -1320,7 +1295,7 @@ public void M() { } }"; var c = GetConversion(program); - Assert.IsFalse(c.IsValid); + Assert.That(!c.IsValid); } [Test] @@ -1337,9 +1312,9 @@ public void M() { } }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); - Assert.IsTrue(c.IsUserDefined); - Assert.IsFalse(c.IsLifted); + Assert.That(c.IsValid); + Assert.That(c.IsUserDefined); + Assert.That(!c.IsLifted); Assert.AreEqual("ni", c.Method.Parameters[0].Name); } @@ -1357,8 +1332,8 @@ public void M() { } }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); - Assert.IsTrue(c.IsUserDefined); + Assert.That(c.IsValid); + Assert.That(c.IsUserDefined); Assert.AreEqual("ui", c.Method.Parameters[0].Name); } @@ -1376,8 +1351,8 @@ public void M() { } }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); - Assert.IsTrue(c.IsUserDefined); + Assert.That(c.IsValid); + Assert.That(c.IsUserDefined); Assert.AreEqual("ui", c.Method.Parameters[0].Name); } @@ -1396,8 +1371,8 @@ public static void Main(string[] args) } }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); - Assert.IsTrue(c.IsUserDefined); + Assert.That(c.IsValid); + Assert.That(c.IsUserDefined); Assert.AreEqual("System.Int16", c.Method.ReturnType.FullName); } @@ -1416,8 +1391,8 @@ public static void Main(string[] args) } }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); - Assert.IsTrue(c.IsUserDefined); + Assert.That(c.IsValid); + Assert.That(c.IsUserDefined); Assert.AreEqual("System.Int16", c.Method.ReturnType.FullName); } @@ -1436,8 +1411,8 @@ public static void Main(string[] args) } }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); - Assert.IsTrue(c.IsUserDefined); + Assert.That(c.IsValid); + Assert.That(c.IsUserDefined); Assert.AreEqual("s", c.Method.Parameters[0].Name); } @@ -1456,8 +1431,8 @@ static void Main() { } }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); - Assert.IsTrue(c.IsUserDefined); + Assert.That(c.IsValid); + Assert.That(c.IsUserDefined); Assert.AreEqual("i", c.Method.Parameters[0].Name); } @@ -1476,8 +1451,8 @@ static void Main() { } }"; var c = GetConversion(program); - Assert.IsFalse(c.IsValid); - Assert.IsTrue(c.IsUserDefined); + Assert.That(!c.IsValid); + Assert.That(c.IsUserDefined); } [Test] @@ -1494,8 +1469,8 @@ static void Main() { } }"; var c = GetConversion(program); - Assert.IsFalse(c.IsValid); - Assert.IsTrue(c.IsUserDefined); + Assert.That(!c.IsValid); + Assert.That(c.IsUserDefined); } [Test] @@ -1513,8 +1488,8 @@ static void Main() { } }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); - Assert.IsTrue(c.IsUserDefined); + Assert.That(c.IsValid); + Assert.That(c.IsUserDefined); Assert.AreEqual("i", c.Method.Parameters[0].Name); } @@ -1537,7 +1512,7 @@ static void Main() { }"; var rr = Resolve(program); - Assert.IsFalse(rr.IsError); + Assert.That(!rr.IsError); Assert.AreEqual("str", rr.Member.Parameters[0].Name); } @@ -1566,8 +1541,8 @@ static void Main() { }"; var c = GetConversion(program); - Assert.IsTrue(c.IsUserDefined); - Assert.IsFalse(c.IsValid); + Assert.That(c.IsUserDefined); + Assert.That(!c.IsValid); } [Test] @@ -1584,11 +1559,11 @@ public void M() { } }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); - Assert.IsTrue(c.ConversionBeforeUserDefinedOperator.IsImplicit); - Assert.IsTrue(c.ConversionBeforeUserDefinedOperator.IsNumericConversion); - Assert.IsTrue(c.ConversionBeforeUserDefinedOperator.IsValid); - Assert.IsTrue(c.ConversionAfterUserDefinedOperator.IsIdentityConversion); + Assert.That(c.IsValid); + Assert.That(c.ConversionBeforeUserDefinedOperator.IsImplicit); + Assert.That(c.ConversionBeforeUserDefinedOperator.IsNumericConversion); + Assert.That(c.ConversionBeforeUserDefinedOperator.IsValid); + Assert.That(c.ConversionAfterUserDefinedOperator.IsIdentityConversion); } [Test] @@ -1604,11 +1579,11 @@ public void M() { } }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); - Assert.IsTrue(c.ConversionBeforeUserDefinedOperator.IsIdentityConversion); - Assert.IsTrue(c.ConversionAfterUserDefinedOperator.IsImplicit); - Assert.IsTrue(c.ConversionAfterUserDefinedOperator.IsNumericConversion); - Assert.IsTrue(c.ConversionAfterUserDefinedOperator.IsValid); + Assert.That(c.IsValid); + Assert.That(c.ConversionBeforeUserDefinedOperator.IsIdentityConversion); + Assert.That(c.ConversionAfterUserDefinedOperator.IsImplicit); + Assert.That(c.ConversionAfterUserDefinedOperator.IsNumericConversion); + Assert.That(c.ConversionAfterUserDefinedOperator.IsValid); } [Test] @@ -1627,9 +1602,9 @@ public static implicit operator JsNumber3(int d) { } }"; var c = GetConversion(program); - Assert.IsTrue(c.IsValid); - Assert.IsTrue(c.IsImplicit); - Assert.IsFalse(c.IsExplicit); + Assert.That(c.IsValid); + Assert.That(c.IsImplicit); + Assert.That(!c.IsExplicit); Assert.AreEqual(Conversion.IdentityConversion, c.ConversionBeforeUserDefinedOperator); Assert.AreEqual(Conversion.IdentityConversion, c.ConversionAfterUserDefinedOperator); } diff --git a/ICSharpCode.Decompiler.Tests/Semantics/ExplicitConversionTest.cs b/ICSharpCode.Decompiler.Tests/Semantics/ExplicitConversionTest.cs index f2bb2b4403..0abed50b61 100644 --- a/ICSharpCode.Decompiler.Tests/Semantics/ExplicitConversionTest.cs +++ b/ICSharpCode.Decompiler.Tests/Semantics/ExplicitConversionTest.cs @@ -58,11 +58,11 @@ Conversion ExplicitConversion(Type from, Type to) [Test] public void PointerConversion() { - Assert.AreEqual(C.ExplicitPointerConversion, ExplicitConversion(typeof(int*), typeof(short))); - Assert.AreEqual(C.ExplicitPointerConversion, ExplicitConversion(typeof(short), typeof(void*))); + Assert.That(ExplicitConversion(typeof(int*), typeof(short)), Is.EqualTo(C.ExplicitPointerConversion)); + Assert.That(ExplicitConversion(typeof(short), typeof(void*)), Is.EqualTo(C.ExplicitPointerConversion)); - Assert.AreEqual(C.ExplicitPointerConversion, ExplicitConversion(typeof(void*), typeof(int*))); - Assert.AreEqual(C.ExplicitPointerConversion, ExplicitConversion(typeof(long*), typeof(byte*))); + Assert.That(ExplicitConversion(typeof(void*), typeof(int*)), Is.EqualTo(C.ExplicitPointerConversion)); + Assert.That(ExplicitConversion(typeof(long*), typeof(byte*)), Is.EqualTo(C.ExplicitPointerConversion)); } [Test] @@ -70,60 +70,60 @@ public void ConversionFromDynamic() { // Explicit dynamic conversion is for resolve results only; // otherwise it's an explicit reference / unboxing conversion - Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(dynamic), typeof(string))); - Assert.AreEqual(C.UnboxingConversion, ExplicitConversion(typeof(dynamic), typeof(int))); + Assert.That(ExplicitConversion(typeof(dynamic), typeof(string)), Is.EqualTo(C.ExplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(dynamic), typeof(int)), Is.EqualTo(C.UnboxingConversion)); var dynamicRR = new ResolveResult(SpecialType.Dynamic); - Assert.AreEqual(C.ExplicitDynamicConversion, conversions.ExplicitConversion(dynamicRR, compilation.FindType(typeof(string)))); - Assert.AreEqual(C.ExplicitDynamicConversion, conversions.ExplicitConversion(dynamicRR, compilation.FindType(typeof(int)))); + Assert.That(conversions.ExplicitConversion(dynamicRR, compilation.FindType(typeof(string))), Is.EqualTo(C.ExplicitDynamicConversion)); + Assert.That(conversions.ExplicitConversion(dynamicRR, compilation.FindType(typeof(int))), Is.EqualTo(C.ExplicitDynamicConversion)); } [Test] public void NumericConversions() { - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(sbyte), typeof(uint))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(sbyte), typeof(char))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(byte), typeof(char))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(byte), typeof(sbyte))); + Assert.That(ExplicitConversion(typeof(sbyte), typeof(uint)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(sbyte), typeof(char)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(byte), typeof(char)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(byte), typeof(sbyte)), Is.EqualTo(C.ExplicitNumericConversion)); // if an implicit conversion exists, ExplicitConversion() should return that - Assert.AreEqual(C.ImplicitNumericConversion, ExplicitConversion(typeof(byte), typeof(int))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(double), typeof(float))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(double), typeof(decimal))); - Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(decimal), typeof(double))); - Assert.AreEqual(C.ImplicitNumericConversion, ExplicitConversion(typeof(int), typeof(decimal))); + Assert.That(ExplicitConversion(typeof(byte), typeof(int)), Is.EqualTo(C.ImplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(double), typeof(float)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(double), typeof(decimal)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(decimal), typeof(double)), Is.EqualTo(C.ExplicitNumericConversion)); + Assert.That(ExplicitConversion(typeof(int), typeof(decimal)), Is.EqualTo(C.ImplicitNumericConversion)); - Assert.AreEqual(C.None, ExplicitConversion(typeof(bool), typeof(int))); - Assert.AreEqual(C.None, ExplicitConversion(typeof(int), typeof(bool))); + Assert.That(ExplicitConversion(typeof(bool), typeof(int)), Is.EqualTo(C.None)); + Assert.That(ExplicitConversion(typeof(int), typeof(bool)), Is.EqualTo(C.None)); } [Test] public void EnumerationConversions() { var explicitEnumerationConversion = C.EnumerationConversion(false, false); - Assert.AreEqual(explicitEnumerationConversion, ExplicitConversion(typeof(sbyte), typeof(StringComparison))); - Assert.AreEqual(explicitEnumerationConversion, ExplicitConversion(typeof(char), typeof(StringComparison))); - Assert.AreEqual(explicitEnumerationConversion, ExplicitConversion(typeof(int), typeof(StringComparison))); - Assert.AreEqual(explicitEnumerationConversion, ExplicitConversion(typeof(decimal), typeof(StringComparison))); - Assert.AreEqual(explicitEnumerationConversion, ExplicitConversion(typeof(StringComparison), typeof(char))); - Assert.AreEqual(explicitEnumerationConversion, ExplicitConversion(typeof(StringComparison), typeof(int))); - Assert.AreEqual(explicitEnumerationConversion, ExplicitConversion(typeof(StringComparison), typeof(decimal))); - Assert.AreEqual(explicitEnumerationConversion, ExplicitConversion(typeof(StringComparison), typeof(StringSplitOptions))); + Assert.That(ExplicitConversion(typeof(sbyte), typeof(StringComparison)), Is.EqualTo(explicitEnumerationConversion)); + Assert.That(ExplicitConversion(typeof(char), typeof(StringComparison)), Is.EqualTo(explicitEnumerationConversion)); + Assert.That(ExplicitConversion(typeof(int), typeof(StringComparison)), Is.EqualTo(explicitEnumerationConversion)); + Assert.That(ExplicitConversion(typeof(decimal), typeof(StringComparison)), Is.EqualTo(explicitEnumerationConversion)); + Assert.That(ExplicitConversion(typeof(StringComparison), typeof(char)), Is.EqualTo(explicitEnumerationConversion)); + Assert.That(ExplicitConversion(typeof(StringComparison), typeof(int)), Is.EqualTo(explicitEnumerationConversion)); + Assert.That(ExplicitConversion(typeof(StringComparison), typeof(decimal)), Is.EqualTo(explicitEnumerationConversion)); + Assert.That(ExplicitConversion(typeof(StringComparison), typeof(StringSplitOptions)), Is.EqualTo(explicitEnumerationConversion)); } [Test] public void NullableConversion_BasedOnIdentityConversion() { - Assert.AreEqual(C.IdentityConversion, ExplicitConversion(typeof(ArraySegment?), typeof(ArraySegment?))); - Assert.AreEqual(C.ImplicitNullableConversion, ExplicitConversion(typeof(ArraySegment), typeof(ArraySegment?))); - Assert.AreEqual(C.ExplicitNullableConversion, ExplicitConversion(typeof(ArraySegment?), typeof(ArraySegment))); + Assert.That(ExplicitConversion(typeof(ArraySegment?), typeof(ArraySegment?)), Is.EqualTo(C.IdentityConversion)); + Assert.That(ExplicitConversion(typeof(ArraySegment), typeof(ArraySegment?)), Is.EqualTo(C.ImplicitNullableConversion)); + Assert.That(ExplicitConversion(typeof(ArraySegment?), typeof(ArraySegment)), Is.EqualTo(C.ExplicitNullableConversion)); } [Test] public void NullableConversion_BasedOnImplicitNumericConversion() { - Assert.AreEqual(C.ImplicitLiftedNumericConversion, ExplicitConversion(typeof(int?), typeof(long?))); - Assert.AreEqual(C.ImplicitLiftedNumericConversion, ExplicitConversion(typeof(int), typeof(long?))); - Assert.AreEqual(C.ExplicitLiftedNumericConversion, ExplicitConversion(typeof(int?), typeof(long))); + Assert.That(ExplicitConversion(typeof(int?), typeof(long?)), Is.EqualTo(C.ImplicitLiftedNumericConversion)); + Assert.That(ExplicitConversion(typeof(int), typeof(long?)), Is.EqualTo(C.ImplicitLiftedNumericConversion)); + Assert.That(ExplicitConversion(typeof(int?), typeof(long)), Is.EqualTo(C.ExplicitLiftedNumericConversion)); } [Test] @@ -131,160 +131,160 @@ public void NullableConversion_BasedOnImplicitEnumerationConversion() { ResolveResult zero = new ConstantResolveResult(compilation.FindType(KnownTypeCode.Int32), 0); ResolveResult one = new ConstantResolveResult(compilation.FindType(KnownTypeCode.Int32), 1); - Assert.AreEqual(C.EnumerationConversion(true, true), conversions.ExplicitConversion(zero, compilation.FindType(typeof(StringComparison?)))); - Assert.AreEqual(C.EnumerationConversion(false, true), conversions.ExplicitConversion(one, compilation.FindType(typeof(StringComparison?)))); + Assert.That(conversions.ExplicitConversion(zero, compilation.FindType(typeof(StringComparison?))), Is.EqualTo(C.EnumerationConversion(true, true))); + Assert.That(conversions.ExplicitConversion(one, compilation.FindType(typeof(StringComparison?))), Is.EqualTo(C.EnumerationConversion(false, true))); } [Test] public void NullableConversion_BasedOnExplicitNumericConversion() { - Assert.AreEqual(C.ExplicitLiftedNumericConversion, ExplicitConversion(typeof(int?), typeof(short?))); - Assert.AreEqual(C.ExplicitLiftedNumericConversion, ExplicitConversion(typeof(int), typeof(short?))); - Assert.AreEqual(C.ExplicitLiftedNumericConversion, ExplicitConversion(typeof(int?), typeof(short))); + Assert.That(ExplicitConversion(typeof(int?), typeof(short?)), Is.EqualTo(C.ExplicitLiftedNumericConversion)); + Assert.That(ExplicitConversion(typeof(int), typeof(short?)), Is.EqualTo(C.ExplicitLiftedNumericConversion)); + Assert.That(ExplicitConversion(typeof(int?), typeof(short)), Is.EqualTo(C.ExplicitLiftedNumericConversion)); } [Test] public void NullableConversion_BasedOnExplicitEnumerationConversion() { C c = C.EnumerationConversion(false, true); // c = explicit lifted enumeration conversion - Assert.AreEqual(c, ExplicitConversion(typeof(int?), typeof(StringComparison?))); - Assert.AreEqual(c, ExplicitConversion(typeof(int), typeof(StringComparison?))); - Assert.AreEqual(c, ExplicitConversion(typeof(int?), typeof(StringComparison))); + Assert.That(ExplicitConversion(typeof(int?), typeof(StringComparison?)), Is.EqualTo(c)); + Assert.That(ExplicitConversion(typeof(int), typeof(StringComparison?)), Is.EqualTo(c)); + Assert.That(ExplicitConversion(typeof(int?), typeof(StringComparison)), Is.EqualTo(c)); - Assert.AreEqual(c, ExplicitConversion(typeof(StringComparison?), typeof(int?))); - Assert.AreEqual(c, ExplicitConversion(typeof(StringComparison), typeof(int?))); - Assert.AreEqual(c, ExplicitConversion(typeof(StringComparison?), typeof(int))); + Assert.That(ExplicitConversion(typeof(StringComparison?), typeof(int?)), Is.EqualTo(c)); + Assert.That(ExplicitConversion(typeof(StringComparison), typeof(int?)), Is.EqualTo(c)); + Assert.That(ExplicitConversion(typeof(StringComparison?), typeof(int)), Is.EqualTo(c)); - Assert.AreEqual(c, ExplicitConversion(typeof(StringComparison?), typeof(StringSplitOptions?))); - Assert.AreEqual(c, ExplicitConversion(typeof(StringComparison), typeof(StringSplitOptions?))); - Assert.AreEqual(c, ExplicitConversion(typeof(StringComparison?), typeof(StringSplitOptions))); + Assert.That(ExplicitConversion(typeof(StringComparison?), typeof(StringSplitOptions?)), Is.EqualTo(c)); + Assert.That(ExplicitConversion(typeof(StringComparison), typeof(StringSplitOptions?)), Is.EqualTo(c)); + Assert.That(ExplicitConversion(typeof(StringComparison?), typeof(StringSplitOptions)), Is.EqualTo(c)); } [Test] public void ExplicitReferenceConversion_SealedClass() { - Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(object), typeof(string))); - Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(IEnumerable), typeof(string))); - Assert.AreEqual(C.None, ExplicitConversion(typeof(IEnumerable), typeof(string))); - Assert.AreEqual(C.None, ExplicitConversion(typeof(IEnumerable), typeof(string))); - Assert.AreEqual(C.ImplicitReferenceConversion, ExplicitConversion(typeof(string), typeof(IEnumerable))); - Assert.AreEqual(C.None, ExplicitConversion(typeof(string), typeof(IEnumerable))); - Assert.AreEqual(C.None, ExplicitConversion(typeof(string), typeof(IEnumerable))); + Assert.That(ExplicitConversion(typeof(object), typeof(string)), Is.EqualTo(C.ExplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(IEnumerable), typeof(string)), Is.EqualTo(C.ExplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(IEnumerable), typeof(string)), Is.EqualTo(C.None)); + Assert.That(ExplicitConversion(typeof(IEnumerable), typeof(string)), Is.EqualTo(C.None)); + Assert.That(ExplicitConversion(typeof(string), typeof(IEnumerable)), Is.EqualTo(C.ImplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(string), typeof(IEnumerable)), Is.EqualTo(C.None)); + Assert.That(ExplicitConversion(typeof(string), typeof(IEnumerable)), Is.EqualTo(C.None)); } [Test] public void ExplicitReferenceConversion_NonSealedClass() { - Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(object), typeof(List))); - Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(IEnumerable), typeof(List))); - Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(IEnumerable), typeof(List))); - Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(IEnumerable), typeof(List))); + Assert.That(ExplicitConversion(typeof(object), typeof(List)), Is.EqualTo(C.ExplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(IEnumerable), typeof(List)), Is.EqualTo(C.ExplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(IEnumerable), typeof(List)), Is.EqualTo(C.ExplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(IEnumerable), typeof(List)), Is.EqualTo(C.ExplicitReferenceConversion)); - Assert.AreEqual(C.ImplicitReferenceConversion, ExplicitConversion(typeof(List), typeof(IEnumerable))); - Assert.AreEqual(C.ImplicitReferenceConversion, ExplicitConversion(typeof(List), typeof(IEnumerable))); - Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(List), typeof(IEnumerable))); + Assert.That(ExplicitConversion(typeof(List), typeof(IEnumerable)), Is.EqualTo(C.ImplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(List), typeof(IEnumerable)), Is.EqualTo(C.ImplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(List), typeof(IEnumerable)), Is.EqualTo(C.ExplicitReferenceConversion)); - Assert.AreEqual(C.None, ExplicitConversion(typeof(List), typeof(List))); - Assert.AreEqual(C.None, ExplicitConversion(typeof(List), typeof(List))); + Assert.That(ExplicitConversion(typeof(List), typeof(List)), Is.EqualTo(C.None)); + Assert.That(ExplicitConversion(typeof(List), typeof(List)), Is.EqualTo(C.None)); } [Test] public void ExplicitReferenceConversion_Interfaces() { - Assert.AreEqual(C.ImplicitReferenceConversion, ExplicitConversion(typeof(IEnumerable), typeof(IEnumerable))); - Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(IEnumerable), typeof(IEnumerable))); - Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(IEnumerable), typeof(IEnumerable))); - Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(IEnumerable), typeof(IEnumerable))); - Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(IEnumerable), typeof(IConvertible))); + Assert.That(ExplicitConversion(typeof(IEnumerable), typeof(IEnumerable)), Is.EqualTo(C.ImplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(IEnumerable), typeof(IEnumerable)), Is.EqualTo(C.ExplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(IEnumerable), typeof(IEnumerable)), Is.EqualTo(C.ExplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(IEnumerable), typeof(IEnumerable)), Is.EqualTo(C.ExplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(IEnumerable), typeof(IConvertible)), Is.EqualTo(C.ExplicitReferenceConversion)); } [Test] public void ExplicitReferenceConversion_Arrays() { - Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(object[]), typeof(string[]))); - Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(dynamic[]), typeof(string[]))); - Assert.AreEqual(C.None, ExplicitConversion(typeof(object[]), typeof(object[,]))); - Assert.AreEqual(C.None, ExplicitConversion(typeof(object[]), typeof(int[]))); - Assert.AreEqual(C.None, ExplicitConversion(typeof(short[]), typeof(int[]))); - Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(Array), typeof(int[]))); + Assert.That(ExplicitConversion(typeof(object[]), typeof(string[])), Is.EqualTo(C.ExplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(dynamic[]), typeof(string[])), Is.EqualTo(C.ExplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(object[]), typeof(object[,])), Is.EqualTo(C.None)); + Assert.That(ExplicitConversion(typeof(object[]), typeof(int[])), Is.EqualTo(C.None)); + Assert.That(ExplicitConversion(typeof(short[]), typeof(int[])), Is.EqualTo(C.None)); + Assert.That(ExplicitConversion(typeof(Array), typeof(int[])), Is.EqualTo(C.ExplicitReferenceConversion)); } [Test] public void ExplicitReferenceConversion_InterfaceToArray() { - Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(ICloneable), typeof(int[]))); - Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(IEnumerable), typeof(string[]))); - Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(IEnumerable), typeof(string[]))); - Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(IEnumerable), typeof(object[]))); - Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(IEnumerable), typeof(dynamic[]))); - Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(IEnumerable), typeof(int[]))); - Assert.AreEqual(C.None, ExplicitConversion(typeof(IEnumerable), typeof(object[,]))); - Assert.AreEqual(C.None, ExplicitConversion(typeof(IEnumerable), typeof(object[]))); + Assert.That(ExplicitConversion(typeof(ICloneable), typeof(int[])), Is.EqualTo(C.ExplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(IEnumerable), typeof(string[])), Is.EqualTo(C.ExplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(IEnumerable), typeof(string[])), Is.EqualTo(C.ExplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(IEnumerable), typeof(object[])), Is.EqualTo(C.ExplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(IEnumerable), typeof(dynamic[])), Is.EqualTo(C.ExplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(IEnumerable), typeof(int[])), Is.EqualTo(C.ExplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(IEnumerable), typeof(object[,])), Is.EqualTo(C.None)); + Assert.That(ExplicitConversion(typeof(IEnumerable), typeof(object[])), Is.EqualTo(C.None)); } [Test] public void ExplicitReferenceConversion_ArrayToInterface() { - Assert.AreEqual(C.ImplicitReferenceConversion, ExplicitConversion(typeof(int[]), typeof(ICloneable))); - Assert.AreEqual(C.ImplicitReferenceConversion, ExplicitConversion(typeof(string[]), typeof(IEnumerable))); - Assert.AreEqual(C.ImplicitReferenceConversion, ExplicitConversion(typeof(string[]), typeof(IEnumerable))); - Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(object[]), typeof(IEnumerable))); - Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(dynamic[]), typeof(IEnumerable))); - Assert.AreEqual(C.ImplicitReferenceConversion, ExplicitConversion(typeof(int[]), typeof(IEnumerable))); - Assert.AreEqual(C.None, ExplicitConversion(typeof(object[,]), typeof(IEnumerable))); - Assert.AreEqual(C.None, ExplicitConversion(typeof(object[]), typeof(IEnumerable))); + Assert.That(ExplicitConversion(typeof(int[]), typeof(ICloneable)), Is.EqualTo(C.ImplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(string[]), typeof(IEnumerable)), Is.EqualTo(C.ImplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(string[]), typeof(IEnumerable)), Is.EqualTo(C.ImplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(object[]), typeof(IEnumerable)), Is.EqualTo(C.ExplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(dynamic[]), typeof(IEnumerable)), Is.EqualTo(C.ExplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(int[]), typeof(IEnumerable)), Is.EqualTo(C.ImplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(object[,]), typeof(IEnumerable)), Is.EqualTo(C.None)); + Assert.That(ExplicitConversion(typeof(object[]), typeof(IEnumerable)), Is.EqualTo(C.None)); } [Test] public void ExplicitReferenceConversion_Delegates() { - Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(MulticastDelegate), typeof(Action))); - Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(Delegate), typeof(Action))); - Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(ICloneable), typeof(Action))); - Assert.AreEqual(C.None, ExplicitConversion(typeof(System.Threading.ThreadStart), typeof(Action))); + Assert.That(ExplicitConversion(typeof(MulticastDelegate), typeof(Action)), Is.EqualTo(C.ExplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(Delegate), typeof(Action)), Is.EqualTo(C.ExplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(ICloneable), typeof(Action)), Is.EqualTo(C.ExplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(System.Threading.ThreadStart), typeof(Action)), Is.EqualTo(C.None)); } [Test] public void ExplicitReferenceConversion_GenericDelegates() { - Assert.AreEqual(C.ImplicitReferenceConversion, ExplicitConversion(typeof(Action), typeof(Action))); - Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(Action), typeof(Action))); + Assert.That(ExplicitConversion(typeof(Action), typeof(Action)), Is.EqualTo(C.ImplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(Action), typeof(Action)), Is.EqualTo(C.ExplicitReferenceConversion)); - Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(Func), typeof(Func))); - Assert.AreEqual(C.ImplicitReferenceConversion, ExplicitConversion(typeof(Func), typeof(Func))); + Assert.That(ExplicitConversion(typeof(Func), typeof(Func)), Is.EqualTo(C.ExplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(Func), typeof(Func)), Is.EqualTo(C.ImplicitReferenceConversion)); - Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(Action), typeof(Action))); - Assert.AreEqual(C.None, ExplicitConversion(typeof(Action), typeof(Action))); - Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(Action), typeof(Action>))); + Assert.That(ExplicitConversion(typeof(Action), typeof(Action)), Is.EqualTo(C.ExplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(Action), typeof(Action)), Is.EqualTo(C.None)); + Assert.That(ExplicitConversion(typeof(Action), typeof(Action>)), Is.EqualTo(C.ExplicitReferenceConversion)); - Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(Func), typeof(Func))); - Assert.AreEqual(C.None, ExplicitConversion(typeof(Func), typeof(Func))); - Assert.AreEqual(C.None, ExplicitConversion(typeof(Func), typeof(Func>))); - Assert.AreEqual(C.None, ExplicitConversion(typeof(Func), typeof(Func>))); + Assert.That(ExplicitConversion(typeof(Func), typeof(Func)), Is.EqualTo(C.ExplicitReferenceConversion)); + Assert.That(ExplicitConversion(typeof(Func), typeof(Func)), Is.EqualTo(C.None)); + Assert.That(ExplicitConversion(typeof(Func), typeof(Func>)), Is.EqualTo(C.None)); + Assert.That(ExplicitConversion(typeof(Func), typeof(Func>)), Is.EqualTo(C.None)); } [Test] public void UnboxingConversion() { - Assert.AreEqual(C.UnboxingConversion, ExplicitConversion(typeof(object), typeof(int))); - Assert.AreEqual(C.UnboxingConversion, ExplicitConversion(typeof(object), typeof(decimal))); - Assert.AreEqual(C.UnboxingConversion, ExplicitConversion(typeof(ValueType), typeof(int))); - Assert.AreEqual(C.UnboxingConversion, ExplicitConversion(typeof(IFormattable), typeof(int))); - Assert.AreEqual(C.None, ExplicitConversion(typeof(IEnumerable), typeof(int))); - Assert.AreEqual(C.UnboxingConversion, ExplicitConversion(typeof(Enum), typeof(StringComparison))); - Assert.AreEqual(C.None, ExplicitConversion(typeof(Enum), typeof(int))); + Assert.That(ExplicitConversion(typeof(object), typeof(int)), Is.EqualTo(C.UnboxingConversion)); + Assert.That(ExplicitConversion(typeof(object), typeof(decimal)), Is.EqualTo(C.UnboxingConversion)); + Assert.That(ExplicitConversion(typeof(ValueType), typeof(int)), Is.EqualTo(C.UnboxingConversion)); + Assert.That(ExplicitConversion(typeof(IFormattable), typeof(int)), Is.EqualTo(C.UnboxingConversion)); + Assert.That(ExplicitConversion(typeof(IEnumerable), typeof(int)), Is.EqualTo(C.None)); + Assert.That(ExplicitConversion(typeof(Enum), typeof(StringComparison)), Is.EqualTo(C.UnboxingConversion)); + Assert.That(ExplicitConversion(typeof(Enum), typeof(int)), Is.EqualTo(C.None)); } [Test] public void LiftedUnboxingConversion() { - Assert.AreEqual(C.UnboxingConversion, ExplicitConversion(typeof(object), typeof(int?))); - Assert.AreEqual(C.UnboxingConversion, ExplicitConversion(typeof(object), typeof(decimal?))); - Assert.AreEqual(C.UnboxingConversion, ExplicitConversion(typeof(ValueType), typeof(int?))); - Assert.AreEqual(C.UnboxingConversion, ExplicitConversion(typeof(IFormattable), typeof(int?))); - Assert.AreEqual(C.None, ExplicitConversion(typeof(IEnumerable), typeof(int?))); - Assert.AreEqual(C.UnboxingConversion, ExplicitConversion(typeof(Enum), typeof(StringComparison?))); - Assert.AreEqual(C.None, ExplicitConversion(typeof(Enum), typeof(int?))); + Assert.That(ExplicitConversion(typeof(object), typeof(int?)), Is.EqualTo(C.UnboxingConversion)); + Assert.That(ExplicitConversion(typeof(object), typeof(decimal?)), Is.EqualTo(C.UnboxingConversion)); + Assert.That(ExplicitConversion(typeof(ValueType), typeof(int?)), Is.EqualTo(C.UnboxingConversion)); + Assert.That(ExplicitConversion(typeof(IFormattable), typeof(int?)), Is.EqualTo(C.UnboxingConversion)); + Assert.That(ExplicitConversion(typeof(IEnumerable), typeof(int?)), Is.EqualTo(C.None)); + Assert.That(ExplicitConversion(typeof(Enum), typeof(StringComparison?)), Is.EqualTo(C.UnboxingConversion)); + Assert.That(ExplicitConversion(typeof(Enum), typeof(int?)), Is.EqualTo(C.None)); } /* TODO: we should probably revive these tests somehow @@ -477,8 +477,8 @@ public void M() { C1 c1 = $(C1)c2$; } }"); - Assert.IsTrue(rr.Conversion.IsValid); - Assert.IsTrue(rr.Conversion.IsUserDefined); + Assert.That(rr.Conversion.IsValid); + Assert.That(rr.Conversion.IsUserDefined); Assert.AreEqual("op_Explicit", rr.Conversion.Method.Name); } @@ -496,8 +496,8 @@ void Run(B b) { T t = $(T)b$; } }"); - Assert.IsTrue(rr.Conversion.IsValid); - Assert.IsTrue(rr.Conversion.IsUserDefined); + Assert.That(rr.Conversion.IsValid); + Assert.That(rr.Conversion.IsUserDefined); Assert.AreEqual("B", rr.Input.Type.Name); } @@ -513,10 +513,10 @@ void Run(T t) { int x = $(int)t$; } }"); - Assert.IsTrue(rr.Conversion.IsValid); - Assert.IsTrue(rr.Conversion.IsUserDefined); + Assert.That(rr.Conversion.IsValid); + Assert.That(rr.Conversion.IsUserDefined); // even though the user-defined conversion is implicit, the combined conversion is explicit - Assert.IsTrue(rr.Conversion.IsExplicit); + Assert.That(rr.Conversion.IsExplicit); } [Test] @@ -534,8 +534,8 @@ void Run(B b) { T t = $(T)b$; } }"); - Assert.IsTrue(rr.Conversion.IsValid); - Assert.IsTrue(rr.Conversion.IsUserDefined); + Assert.That(rr.Conversion.IsValid); + Assert.That(rr.Conversion.IsUserDefined); Assert.AreEqual("b", rr.Conversion.Method.Parameters.Single().Name); } @@ -553,8 +553,8 @@ public void M() { } }"; var rr = Resolve(program); - Assert.IsTrue(rr.Conversion.IsValid); - Assert.IsTrue(rr.Conversion.IsUserDefined); + Assert.That(rr.Conversion.IsValid); + Assert.That(rr.Conversion.IsUserDefined); Assert.AreEqual("i", rr.Conversion.Method.Parameters[0].Name); } @@ -572,8 +572,8 @@ public void M() { } }"; var rr = Resolve(program); - Assert.IsTrue(rr.Conversion.IsValid); - Assert.IsTrue(rr.Conversion.IsUserDefined); + Assert.That(rr.Conversion.IsValid); + Assert.That(rr.Conversion.IsUserDefined); Assert.AreEqual("ui", rr.Conversion.Method.Parameters[0].Name); } @@ -591,8 +591,8 @@ public void M() { } }"; var rr = Resolve(program); - Assert.IsTrue(rr.Conversion.IsValid); - Assert.IsTrue(rr.Conversion.IsUserDefined); + Assert.That(rr.Conversion.IsValid); + Assert.That(rr.Conversion.IsUserDefined); Assert.AreEqual("i", rr.Conversion.Method.Parameters[0].Name); } @@ -610,7 +610,7 @@ public void M() { } }"; var rr = Resolve(program); - Assert.IsFalse(rr.Conversion.IsValid); + Assert.That(!rr.Conversion.IsValid); } [Test] @@ -627,8 +627,8 @@ public void M() { } }"; var rr = Resolve(program); - Assert.IsTrue(rr.Conversion.IsValid); - Assert.IsTrue(rr.Conversion.IsUserDefined); + Assert.That(rr.Conversion.IsValid); + Assert.That(rr.Conversion.IsUserDefined); Assert.AreEqual("i", rr.Conversion.Method.Parameters[0].Name); } @@ -646,8 +646,8 @@ public void M() { } }"; var rr = Resolve(program); - Assert.IsTrue(rr.Conversion.IsValid); - Assert.IsTrue(rr.Conversion.IsUserDefined); + Assert.That(rr.Conversion.IsValid); + Assert.That(rr.Conversion.IsUserDefined); Assert.AreEqual("us", rr.Conversion.Method.Parameters[0].Name); } @@ -665,8 +665,8 @@ public void M() { } }"; var rr = Resolve(program); - Assert.IsTrue(rr.Conversion.IsValid); - Assert.IsTrue(rr.Conversion.IsUserDefined); + Assert.That(rr.Conversion.IsValid); + Assert.That(rr.Conversion.IsUserDefined); Assert.AreEqual("ui", rr.Conversion.Method.Parameters[0].Name); } @@ -684,7 +684,7 @@ public void M() { } }"; var rr = Resolve(program); - Assert.IsFalse(rr.Conversion.IsValid); + Assert.That(!rr.Conversion.IsValid); } [Test] @@ -703,7 +703,7 @@ public void M() { } }"; var rr = Resolve(program); - Assert.IsFalse(rr.Conversion.IsValid); + Assert.That(!rr.Conversion.IsValid); } [Test] @@ -719,9 +719,9 @@ public void M(int? i) { } }"; var rr = Resolve(program); - Assert.IsTrue(rr.Conversion.IsValid); - Assert.IsTrue(rr.Conversion.IsUserDefined); - Assert.IsTrue(rr.Conversion.IsLifted); + Assert.That(rr.Conversion.IsValid); + Assert.That(rr.Conversion.IsUserDefined); + Assert.That(rr.Conversion.IsLifted); } [Test] @@ -737,9 +737,9 @@ public void M(int i) { } }"; var rr = Resolve(program); - Assert.IsTrue(rr.Conversion.IsValid); - Assert.IsTrue(rr.Conversion.IsUserDefined); - Assert.IsFalse(rr.Conversion.IsLifted); + Assert.That(rr.Conversion.IsValid); + Assert.That(rr.Conversion.IsUserDefined); + Assert.That(!rr.Conversion.IsLifted); } [Test] @@ -756,9 +756,9 @@ public void M(int? i) { } }"; var rr = Resolve(program); - Assert.IsTrue(rr.Conversion.IsValid); - Assert.IsTrue(rr.Conversion.IsUserDefined); - Assert.IsFalse(rr.Conversion.IsLifted); + Assert.That(rr.Conversion.IsValid); + Assert.That(rr.Conversion.IsUserDefined); + Assert.That(!rr.Conversion.IsLifted); Assert.AreEqual("i", rr.Conversion.Method.Parameters[0].Name); } @@ -776,9 +776,9 @@ public void M() { } }"; var rr = Resolve(program); - Assert.IsTrue(rr.Conversion.IsValid); - Assert.IsTrue(rr.Conversion.IsUserDefined); - Assert.IsFalse(rr.Conversion.IsLifted); + Assert.That(rr.Conversion.IsValid); + Assert.That(rr.Conversion.IsUserDefined); + Assert.That(!rr.Conversion.IsLifted); Assert.AreEqual("ni", rr.Conversion.Method.Parameters[0].Name); } @@ -796,8 +796,8 @@ public void M() { } }"; var rr = Resolve(program); - Assert.IsTrue(rr.Conversion.IsValid); - Assert.IsTrue(rr.Conversion.IsUserDefined); + Assert.That(rr.Conversion.IsValid); + Assert.That(rr.Conversion.IsUserDefined); Assert.AreEqual("ui", rr.Conversion.Method.Parameters[0].Name); } @@ -815,8 +815,8 @@ public void M() { } }"; var rr = Resolve(program); - Assert.IsTrue(rr.Conversion.IsValid); - Assert.IsTrue(rr.Conversion.IsUserDefined); + Assert.That(rr.Conversion.IsValid); + Assert.That(rr.Conversion.IsUserDefined); Assert.AreEqual("ui", rr.Conversion.Method.Parameters[0].Name); } @@ -833,10 +833,10 @@ public void M(int? i) { } }"; var rr = Resolve(program); - Assert.IsTrue(rr.Conversion.IsValid); - Assert.IsTrue(rr.Conversion.IsUserDefined); - Assert.IsTrue(rr.Conversion.IsLifted); - Assert.IsTrue(rr.Input is LocalResolveResult); + Assert.That(rr.Conversion.IsValid); + Assert.That(rr.Conversion.IsUserDefined); + Assert.That(rr.Conversion.IsLifted); + Assert.That(rr.Input is LocalResolveResult); } [Test] @@ -854,8 +854,8 @@ public static void Main(string[] args) } }"; var rr = Resolve(program); - Assert.IsTrue(rr.Conversion.IsValid); - Assert.IsTrue(rr.Conversion.IsUserDefined); + Assert.That(rr.Conversion.IsValid); + Assert.That(rr.Conversion.IsUserDefined); Assert.AreEqual("System.Int16", rr.Conversion.Method.ReturnType.FullName); } @@ -874,8 +874,8 @@ public static void Main(string[] args) } }"; var rr = Resolve(program); - Assert.IsTrue(rr.Conversion.IsValid); - Assert.IsTrue(rr.Conversion.IsUserDefined); + Assert.That(rr.Conversion.IsValid); + Assert.That(rr.Conversion.IsUserDefined); Assert.AreEqual("s", rr.Conversion.Method.Parameters[0].Name); } @@ -893,8 +893,8 @@ static void Main() { } }"; var rr = Resolve(program); - Assert.IsTrue(rr.Conversion.IsValid); - Assert.IsTrue(rr.Conversion.IsUserDefined); + Assert.That(rr.Conversion.IsValid); + Assert.That(rr.Conversion.IsUserDefined); Assert.AreEqual("ci", rr.Conversion.Method.Parameters[0].Name); } @@ -912,11 +912,11 @@ public void M() { } }"; var rr = Resolve(program); - Assert.IsTrue(rr.Conversion.IsValid); - Assert.IsTrue(rr.Conversion.ConversionBeforeUserDefinedOperator.IsValid); - Assert.IsTrue(rr.Conversion.ConversionBeforeUserDefinedOperator.IsExplicit); - Assert.IsTrue(rr.Conversion.ConversionBeforeUserDefinedOperator.IsNumericConversion); - Assert.IsTrue(rr.Conversion.ConversionAfterUserDefinedOperator.IsIdentityConversion); + Assert.That(rr.Conversion.IsValid); + Assert.That(rr.Conversion.ConversionBeforeUserDefinedOperator.IsValid); + Assert.That(rr.Conversion.ConversionBeforeUserDefinedOperator.IsExplicit); + Assert.That(rr.Conversion.ConversionBeforeUserDefinedOperator.IsNumericConversion); + Assert.That(rr.Conversion.ConversionAfterUserDefinedOperator.IsIdentityConversion); } [Test] @@ -932,11 +932,11 @@ public void M() { } }"; var rr = Resolve(program); - Assert.IsTrue(rr.Conversion.IsValid); - Assert.IsTrue(rr.Conversion.ConversionBeforeUserDefinedOperator.IsIdentityConversion); - Assert.IsTrue(rr.Conversion.ConversionAfterUserDefinedOperator.IsValid); - Assert.IsTrue(rr.Conversion.ConversionAfterUserDefinedOperator.IsExplicit); - Assert.IsTrue(rr.Conversion.ConversionAfterUserDefinedOperator.IsNumericConversion); + Assert.That(rr.Conversion.IsValid); + Assert.That(rr.Conversion.ConversionBeforeUserDefinedOperator.IsIdentityConversion); + Assert.That(rr.Conversion.ConversionAfterUserDefinedOperator.IsValid); + Assert.That(rr.Conversion.ConversionAfterUserDefinedOperator.IsExplicit); + Assert.That(rr.Conversion.ConversionAfterUserDefinedOperator.IsNumericConversion); }*/ } } diff --git a/ICSharpCode.Decompiler.Tests/Semantics/OverloadResolutionTests.cs b/ICSharpCode.Decompiler.Tests/Semantics/OverloadResolutionTests.cs index 5a72ad5b2c..cabe83281b 100644 --- a/ICSharpCode.Decompiler.Tests/Semantics/OverloadResolutionTests.cs +++ b/ICSharpCode.Decompiler.Tests/Semantics/OverloadResolutionTests.cs @@ -86,10 +86,10 @@ public void PreferIntOverUInt() { OverloadResolution r = new OverloadResolution(compilation, MakeArgumentList(typeof(ushort))); var c1 = MakeMethod(typeof(int)); - Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(c1)); - Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(MakeMethod(typeof(uint)))); - Assert.IsFalse(r.IsAmbiguous); - Assert.AreSame(c1, r.BestCandidate); + Assert.That(r.AddCandidate(c1), Is.EqualTo(OverloadResolutionErrors.None)); + Assert.That(r.AddCandidate(MakeMethod(typeof(uint))), Is.EqualTo(OverloadResolutionErrors.None)); + Assert.That(!r.IsAmbiguous); + Assert.That(r.BestCandidate, Is.SameAs(c1)); } [Test] @@ -98,66 +98,66 @@ public void PreferUIntOverLong_FromIntLiteral() ResolveResult[] args = { new ConstantResolveResult(compilation.FindType(KnownTypeCode.Int32), 1) }; OverloadResolution r = new OverloadResolution(compilation, args); var c1 = MakeMethod(typeof(uint)); - Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(c1)); - Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(MakeMethod(typeof(long)))); - Assert.IsFalse(r.IsAmbiguous); - Assert.AreSame(c1, r.BestCandidate); + Assert.That(r.AddCandidate(c1), Is.EqualTo(OverloadResolutionErrors.None)); + Assert.That(r.AddCandidate(MakeMethod(typeof(long))), Is.EqualTo(OverloadResolutionErrors.None)); + Assert.That(!r.IsAmbiguous); + Assert.That(r.BestCandidate, Is.SameAs(c1)); } [Test] public void NullableIntAndNullableUIntIsAmbiguous() { OverloadResolution r = new OverloadResolution(compilation, MakeArgumentList(typeof(ushort?))); - Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(MakeMethod(typeof(int?)))); - Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(MakeMethod(typeof(uint?)))); - Assert.AreEqual(OverloadResolutionErrors.AmbiguousMatch, r.BestCandidateErrors); + Assert.That(r.AddCandidate(MakeMethod(typeof(int?))), Is.EqualTo(OverloadResolutionErrors.None)); + Assert.That(r.AddCandidate(MakeMethod(typeof(uint?))), Is.EqualTo(OverloadResolutionErrors.None)); + Assert.That(r.BestCandidateErrors, Is.EqualTo(OverloadResolutionErrors.AmbiguousMatch)); // then adding a matching overload solves the ambiguity: - Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(MakeMethod(typeof(ushort?)))); - Assert.AreEqual(OverloadResolutionErrors.None, r.BestCandidateErrors); - Assert.IsNull(r.BestCandidateAmbiguousWith); + Assert.That(r.AddCandidate(MakeMethod(typeof(ushort?))), Is.EqualTo(OverloadResolutionErrors.None)); + Assert.That(r.BestCandidateErrors, Is.EqualTo(OverloadResolutionErrors.None)); + Assert.That(r.BestCandidateAmbiguousWith, Is.Null); } [Test] public void ParamsMethodMatchesEmptyArgumentList() { OverloadResolution r = new OverloadResolution(compilation, MakeArgumentList()); - Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(MakeParamsMethod(typeof(int[])))); - Assert.IsTrue(r.BestCandidateIsExpandedForm); + Assert.That(r.AddCandidate(MakeParamsMethod(typeof(int[]))), Is.EqualTo(OverloadResolutionErrors.None)); + Assert.That(r.BestCandidateIsExpandedForm); } [Test] public void ParamsMethodMatchesOneArgumentInExpandedForm() { OverloadResolution r = new OverloadResolution(compilation, MakeArgumentList(typeof(int))); - Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(MakeParamsMethod(typeof(int[])))); - Assert.IsTrue(r.BestCandidateIsExpandedForm); + Assert.That(r.AddCandidate(MakeParamsMethod(typeof(int[]))), Is.EqualTo(OverloadResolutionErrors.None)); + Assert.That(r.BestCandidateIsExpandedForm); } [Test] public void ParamsMethodMatchesInUnexpandedForm() { OverloadResolution r = new OverloadResolution(compilation, MakeArgumentList(typeof(int[]))); - Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(MakeParamsMethod(typeof(int[])))); - Assert.IsFalse(r.BestCandidateIsExpandedForm); + Assert.That(r.AddCandidate(MakeParamsMethod(typeof(int[]))), Is.EqualTo(OverloadResolutionErrors.None)); + Assert.That(!r.BestCandidateIsExpandedForm); } [Test] public void LessArgumentsPassedToParamsIsBetter() { OverloadResolution r = new OverloadResolution(compilation, MakeArgumentList(typeof(int), typeof(int), typeof(int))); - Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(MakeParamsMethod(typeof(int[])))); - Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(MakeParamsMethod(typeof(int), typeof(int[])))); - Assert.IsFalse(r.IsAmbiguous); - Assert.AreEqual(2, r.BestCandidate.Parameters.Count); + Assert.That(r.AddCandidate(MakeParamsMethod(typeof(int[]))), Is.EqualTo(OverloadResolutionErrors.None)); + Assert.That(r.AddCandidate(MakeParamsMethod(typeof(int), typeof(int[]))), Is.EqualTo(OverloadResolutionErrors.None)); + Assert.That(!r.IsAmbiguous); + Assert.That(r.BestCandidate.Parameters.Count, Is.EqualTo(2)); } [Test] public void CallInvalidParamsDeclaration() { OverloadResolution r = new OverloadResolution(compilation, MakeArgumentList(typeof(int[,]))); - Assert.AreEqual(OverloadResolutionErrors.ArgumentTypeMismatch, r.AddCandidate(MakeParamsMethod(typeof(int)))); - Assert.IsFalse(r.BestCandidateIsExpandedForm); + Assert.That(r.AddCandidate(MakeParamsMethod(typeof(int))), Is.EqualTo(OverloadResolutionErrors.ArgumentTypeMismatch)); + Assert.That(!r.BestCandidateIsExpandedForm); } [Test] @@ -167,10 +167,10 @@ public void PreferMethodWithoutOptionalParameters() var m2 = MakeMethod(1); OverloadResolution r = new OverloadResolution(compilation, MakeArgumentList()); - Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(m1)); - Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(m2)); - Assert.IsFalse(r.IsAmbiguous); - Assert.AreSame(m1, r.BestCandidate); + Assert.That(r.AddCandidate(m1), Is.EqualTo(OverloadResolutionErrors.None)); + Assert.That(r.AddCandidate(m2), Is.EqualTo(OverloadResolutionErrors.None)); + Assert.That(!r.IsAmbiguous); + Assert.That(r.BestCandidate, Is.SameAs(m1)); } [Test] @@ -186,22 +186,22 @@ public void SkeetEvilOverloadResolution() // Call: Foo(); OverloadResolution o; o = new OverloadResolution(compilation, new ResolveResult[0], typeArguments: new[] { compilation.FindType(typeof(int)) }); - Assert.AreEqual(OverloadResolutionErrors.None, o.AddCandidate(resolvedM1)); - Assert.AreEqual(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint, o.AddCandidate(resolvedM2)); - Assert.AreSame(resolvedM1, o.BestCandidate); + Assert.That(o.AddCandidate(resolvedM1), Is.EqualTo(OverloadResolutionErrors.None)); + Assert.That(o.AddCandidate(resolvedM2), Is.EqualTo(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint)); + Assert.That(o.BestCandidate, Is.SameAs(resolvedM1)); // Call: Foo(); o = new OverloadResolution(compilation, new ResolveResult[0], typeArguments: new[] { compilation.FindType(typeof(string)) }); - Assert.AreEqual(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint, o.AddCandidate(resolvedM1)); - Assert.AreEqual(OverloadResolutionErrors.None, o.AddCandidate(resolvedM2)); - Assert.AreSame(resolvedM2, o.BestCandidate); + Assert.That(o.AddCandidate(resolvedM1), Is.EqualTo(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint)); + Assert.That(o.AddCandidate(resolvedM2), Is.EqualTo(OverloadResolutionErrors.None)); + Assert.That(o.BestCandidate, Is.SameAs(resolvedM2)); // Call: Foo(); o = new OverloadResolution(compilation, new ResolveResult[0], typeArguments: new[] { compilation.FindType(typeof(int?)) }); - Assert.AreEqual(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint, o.AddCandidate(resolvedM1)); - Assert.AreEqual(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint, o.AddCandidate(resolvedM2)); - Assert.AreEqual(OverloadResolutionErrors.None, o.AddCandidate(resolvedM3)); - Assert.AreSame(resolvedM3, o.BestCandidate); + Assert.That(o.AddCandidate(resolvedM1), Is.EqualTo(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint)); + Assert.That(o.AddCandidate(resolvedM2), Is.EqualTo(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint)); + Assert.That(o.AddCandidate(resolvedM3), Is.EqualTo(OverloadResolutionErrors.None)); + Assert.That(o.BestCandidate, Is.SameAs(resolvedM3)); } class SkeetEvilOverloadResolutionTestCase @@ -276,10 +276,10 @@ public void BetterConversionByLambdaReturnValue() }; OverloadResolution r = new OverloadResolution(compilation, args); - Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(m1)); - Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(m2)); - Assert.AreSame(m2, r.BestCandidate); - Assert.AreEqual(OverloadResolutionErrors.None, r.BestCandidateErrors); + Assert.That(r.AddCandidate(m1), Is.EqualTo(OverloadResolutionErrors.None)); + Assert.That(r.AddCandidate(m2), Is.EqualTo(OverloadResolutionErrors.None)); + Assert.That(r.BestCandidate, Is.SameAs(m2)); + Assert.That(r.BestCandidateErrors, Is.EqualTo(OverloadResolutionErrors.None)); } [Test] @@ -294,10 +294,10 @@ public void BetterConversionByLambdaReturnValue_ExpressionTree() }; OverloadResolution r = new OverloadResolution(compilation, args); - Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(m1)); - Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(m2)); - Assert.AreSame(m2, r.BestCandidate); - Assert.AreEqual(OverloadResolutionErrors.None, r.BestCandidateErrors); + Assert.That(r.AddCandidate(m1), Is.EqualTo(OverloadResolutionErrors.None)); + Assert.That(r.AddCandidate(m2), Is.EqualTo(OverloadResolutionErrors.None)); + Assert.That(r.BestCandidate, Is.SameAs(m2)); + Assert.That(r.BestCandidateErrors, Is.EqualTo(OverloadResolutionErrors.None)); } [Test] @@ -312,9 +312,9 @@ public void Lambda_DelegateAndExpressionTreeOverloadsAreAmbiguous() }; OverloadResolution r = new OverloadResolution(compilation, args); - Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(m1)); - Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(m2)); - Assert.AreEqual(OverloadResolutionErrors.AmbiguousMatch, r.BestCandidateErrors); + Assert.That(r.AddCandidate(m1), Is.EqualTo(OverloadResolutionErrors.None)); + Assert.That(r.AddCandidate(m2), Is.EqualTo(OverloadResolutionErrors.None)); + Assert.That(r.BestCandidateErrors, Is.EqualTo(OverloadResolutionErrors.AmbiguousMatch)); } [Test, Ignore("Overload Resolution bug")] @@ -329,10 +329,10 @@ public void BetterFunctionMemberIsNotTransitive() OverloadResolution r = new OverloadResolution(compilation, args); foreach (var method in container.GetMethods(m => m.Name == "Method")) { - Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(method)); + Assert.That(r.AddCandidate(method), Is.EqualTo(OverloadResolutionErrors.None)); } - Assert.AreEqual(container.GetMethods(m => m.Name == "Method").Last(), r.BestCandidate); + Assert.That(r.BestCandidate, Is.EqualTo(container.GetMethods(m => m.Name == "Method").Last())); } class BetterFunctionMemberIsNotTransitiveTestCase diff --git a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/WeirdEnums.cs b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/WeirdEnums.cs index f285a6a9c2..16e799a2de 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/WeirdEnums.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/WeirdEnums.cs @@ -10,6 +10,19 @@ public enum BooleanEnum : bool Max = byte.MaxValue } + public enum EnumWithNestedClass + { +#pragma warning disable format + // error: nested types are not permitted in C#. + public class NestedClass + { + } + , +#pragma warning enable format + Zero, + One + } + public enum NativeIntEnum : IntPtr { Zero = 0L, diff --git a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/WeirdEnums.il b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/WeirdEnums.il index 29356ef8aa..d4859859df 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/WeirdEnums.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/WeirdEnums.il @@ -34,3 +34,33 @@ .field public static literal valuetype TestEnum.NativeIntEnum One = int64(1) .field public static literal valuetype TestEnum.NativeIntEnum FortyTwo = int64(42) } + +.class nested public auto ansi sealed TestEnum.EnumWithNestedClass + extends [System.Runtime]System.Enum +{ + // Nested Types + .class nested public auto ansi beforefieldinit NestedClass + extends [mscorlib]System.Object + { + // Methods + .method public hidebysig specialname rtspecialname + instance void .ctor () cil managed + { + // Method begins at RVA 0x206c + // Code size 8 (0x8) + .maxstack 8 + + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: nop + IL_0007: ret + } // end of method TestEnum.NestedClass::.ctor + + } // end of class NestedClass + + // Fields + .field public specialname rtspecialname int32 value__ + .field public static literal valuetype TestEnum.EnumWithNestedClass Zero = int32(0) + .field public static literal valuetype TestEnum.EnumWithNestedClass One = int32(1) + +} // end of class EnumWithNestedClass \ No newline at end of file diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ExpressionTrees.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ExpressionTrees.cs index 427d57153a..039804db78 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ExpressionTrees.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ExpressionTrees.cs @@ -223,15 +223,15 @@ public SimpleTypeWithMultipleCtors(int i) private dynamic ViewBag; public static readonly object[] SupportedMethods = new object[2] { - ToCode(null, () => ((IQueryable)null).Aggregate((object o1, object o2) => null)), - ToCode(null, () => ((IEnumerable)null).Aggregate((object o1, object o2) => null)) + ToCode(null, () => ((IQueryable)null).Aggregate((object o1, object o2) => (object)null)), + ToCode(null, () => ((IEnumerable)null).Aggregate((object o1, object o2) => (object)null)) }; public static readonly object[] SupportedMethods2 = new object[4] { - ToCode(null, () => ((IQueryable)null).Aggregate(null, (object o1, object o2) => null)), - ToCode(null, () => ((IQueryable)null).Aggregate((object)null, (Expression>)((object o1, object o2) => null), (Expression>)((object o) => null))), - ToCode(null, () => ((IEnumerable)null).Aggregate(null, (object o1, object o2) => null)), - ToCode(null, () => ((IEnumerable)null).Aggregate((object)null, (Func)((object o1, object o2) => null), (Func)((object o) => null))) + ToCode(null, () => ((IQueryable)null).Aggregate(null, (object o1, object o2) => (object)null)), + ToCode(null, () => ((IQueryable)null).Aggregate(null, (object o1, object o2) => (object)null, (object o) => (object)null)), + ToCode(null, () => ((IEnumerable)null).Aggregate(null, (object o1, object o2) => (object)null)), + ToCode(null, () => ((IEnumerable)null).Aggregate(null, (object o1, object o2) => (object)null, (object o) => (object)null)) }; public static void TestCall(object a) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/FixProxyCalls.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/FixProxyCalls.cs index 0675b77781..4b14803d76 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/FixProxyCalls.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/FixProxyCalls.cs @@ -120,7 +120,7 @@ public class Issue1660 : Issue1660Base public Action M(object state) { return delegate (object x) { - base.BaseCall(x, state, (Func)(() => null)); + base.BaseCall(x, state, () => (object)null); }; } } diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/NullableRefTypes.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/NullableRefTypes.cs index 5450173574..a8949dc3c9 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/NullableRefTypes.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/NullableRefTypes.cs @@ -1,5 +1,6 @@ #nullable enable using System; +using System.Collections; using System.Collections.Generic; namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -139,4 +140,48 @@ public static void CallDefault() Console.WriteLine(format, num, num2, tuple); } } + + public class T06_ExplicitInterfaceImplementation : IEnumerable>, IEnumerable + { + // TODO: declaring type is not yet rendered with nullability annotations from the base type + IEnumerator> IEnumerable>.GetEnumerator() + { + yield return new KeyValuePair("a", "b"); + } + + IEnumerator IEnumerable.GetEnumerator() + { + throw new NotImplementedException(); + } + } + + public class T07_ExplicitInterfaceImplementation : IEnumerator>, IEnumerator, IDisposable + { + KeyValuePair IEnumerator>.Current { + get { + throw new NotImplementedException(); + } + } + + object IEnumerator.Current { + get { + throw new NotImplementedException(); + } + } + + void IDisposable.Dispose() + { + throw new NotImplementedException(); + } + + bool IEnumerator.MoveNext() + { + throw new NotImplementedException(); + } + + void IEnumerator.Reset() + { + throw new NotImplementedException(); + } + } } diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.cs index cbcb2635fa..856c02028e 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.cs @@ -1444,7 +1444,11 @@ public static void Issue1745(string aaa) public static bool DoNotRemoveAssignmentBeforeSwitch(string x, out ConsoleKey key) { +#if NET40 || !ROSLYN key = (ConsoleKey)0; +#else + key = ConsoleKey.None; +#endif switch (x) { case "A": @@ -1457,7 +1461,11 @@ public static bool DoNotRemoveAssignmentBeforeSwitch(string x, out ConsoleKey ke key = ConsoleKey.C; break; } +#if NET40 || !ROSLYN return key != (ConsoleKey)0; +#else + return key != ConsoleKey.None; +#endif } public static void Issue1767(string s) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/TupleTests.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/TupleTests.cs index f0e19c1ba4..90692b1fff 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/TupleTests.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/TupleTests.cs @@ -77,7 +77,7 @@ public struct GenericStruct public int AccessPartiallyNamed => PartiallyNamed.a + PartiallyNamed.Item3; public ValueTuple NewTuple1 => new ValueTuple(1); - public (int a, int b) NewTuple2 => (1, 2); + public (int a, int b) NewTuple2 => (a: 1, b: 2); public object BoxedTuple10 => (1, 2, 3, 4, 5, 6, 7, 8, 9, 10); public (uint, int) SwapUnnamed => (Unnamed2.Item2, Unnamed2.Item1); @@ -115,7 +115,7 @@ public void UnnamedTupleRef(ref (int, string, Action, dynamic) tuple) public void NamedTupleOut(out (int A, string B, Action C, dynamic D) tuple) { - tuple = (42, "Hello", Console.WriteLine, null); + tuple = (A: 42, B: "Hello", C: Console.WriteLine, D: null); } public void NamedTupleIn(in (int A, string B, Action C, dynamic D) tuple) @@ -141,6 +141,27 @@ public void UseDict() Console.WriteLine(TupleDict.Values.ToList().First().d); } + private static (string, string) Issue3014a(string[] args) + { + return (from v in args + select (Name: v, Value: v) into kvp + orderby kvp.Name + select kvp).First(); + } + + private static (string, string) Issue3014b(string[] args) + { + return (from v in args + select ((string Name, string Value))GetTuple() into kvp + orderby kvp.Name + select kvp).First(); + + (string, string) GetTuple() + { + return (args[0], args[1]); + } + } + public void Issue1174() { Console.WriteLine((1, 2, 3).GetHashCode()); diff --git a/ICSharpCode.Decompiler.Tests/TypeSystem/ReflectionHelperTests.cs b/ICSharpCode.Decompiler.Tests/TypeSystem/ReflectionHelperTests.cs index 3686dbfcf4..75e6959642 100644 --- a/ICSharpCode.Decompiler.Tests/TypeSystem/ReflectionHelperTests.cs +++ b/ICSharpCode.Decompiler.Tests/TypeSystem/ReflectionHelperTests.cs @@ -36,8 +36,8 @@ public unsafe class ReflectionHelperTests void TestFindType(Type type) { IType t = compilation.FindType(type); - Assert.IsNotNull(t, type.FullName); - Assert.AreEqual(type.FullName, t.ReflectionName); + Assert.That(t, Is.Not.Null, type.FullName); + Assert.That(t.ReflectionName, Is.EqualTo(type.FullName)); } [Test] @@ -73,83 +73,70 @@ public void TestGetInnerClassInGenericClass2() [Test] public void TestToTypeReferenceInnerClass() { - Assert.AreEqual("System.Environment+SpecialFolder", - compilation.FindType(typeof(Environment.SpecialFolder)).ReflectionName); + Assert.That(compilation.FindType(typeof(Environment.SpecialFolder)).ReflectionName, Is.EqualTo("System.Environment+SpecialFolder")); } [Test] public void TestToTypeReferenceUnboundGenericClass() { - Assert.AreEqual("System.Action`1", - compilation.FindType(typeof(Action<>)).ReflectionName); - Assert.AreEqual("System.Action`2", - compilation.FindType(typeof(Action<,>)).ReflectionName); + Assert.That(compilation.FindType(typeof(Action<>)).ReflectionName, Is.EqualTo("System.Action`1")); + Assert.That(compilation.FindType(typeof(Action<,>)).ReflectionName, Is.EqualTo("System.Action`2")); } [Test] public void TestToTypeReferenceBoundGenericClass() { - Assert.AreEqual("System.Action`1[[System.String]]", - compilation.FindType(typeof(Action)).ReflectionName); - Assert.AreEqual("System.Action`2[[System.Int32],[System.Int16]]", - compilation.FindType(typeof(Action)).ReflectionName); + Assert.That(compilation.FindType(typeof(Action)).ReflectionName, Is.EqualTo("System.Action`1[[System.String]]")); + Assert.That(compilation.FindType(typeof(Action)).ReflectionName, Is.EqualTo("System.Action`2[[System.Int32],[System.Int16]]")); } [Test] public void TestToTypeReferenceNullableType() { - Assert.AreEqual("System.Nullable`1[[System.Int32]]", - compilation.FindType(typeof(int?)).ReflectionName); + Assert.That(compilation.FindType(typeof(int?)).ReflectionName, Is.EqualTo("System.Nullable`1[[System.Int32]]")); } [Test] public void TestToTypeReferenceInnerClassInUnboundGenericType() { - Assert.AreEqual("System.Collections.Generic.Dictionary`2+ValueCollection", - compilation.FindType(typeof(Dictionary<,>.ValueCollection)).ReflectionName); + Assert.That(compilation.FindType(typeof(Dictionary<,>.ValueCollection)).ReflectionName, Is.EqualTo("System.Collections.Generic.Dictionary`2+ValueCollection")); } [Test] public void TestToTypeReferenceInnerClassInBoundGenericType() { - Assert.AreEqual("System.Collections.Generic.Dictionary`2+KeyCollection[[System.String],[System.Int32]]", - compilation.FindType(typeof(Dictionary.KeyCollection)).ReflectionName); + Assert.That(compilation.FindType(typeof(Dictionary.KeyCollection)).ReflectionName, Is.EqualTo("System.Collections.Generic.Dictionary`2+KeyCollection[[System.String],[System.Int32]]")); } [Test] public void TestToTypeReferenceArrayType() { - Assert.AreEqual(typeof(int[]).FullName, - compilation.FindType(typeof(int[])).ReflectionName); + Assert.That(compilation.FindType(typeof(int[])).ReflectionName, Is.EqualTo(typeof(int[]).FullName)); } [Test] public void TestToTypeReferenceMultidimensionalArrayType() { - Assert.AreEqual(typeof(int[,]).FullName, - compilation.FindType(typeof(int[,])).ReflectionName); + Assert.That(compilation.FindType(typeof(int[,])).ReflectionName, Is.EqualTo(typeof(int[,]).FullName)); } [Test] public void TestToTypeReferenceJaggedMultidimensionalArrayType() { - Assert.AreEqual(typeof(int[,][,,]).FullName, - compilation.FindType(typeof(int[,][,,])).ReflectionName); + Assert.That(compilation.FindType(typeof(int[,][,,])).ReflectionName, Is.EqualTo(typeof(int[,][,,]).FullName)); } [Test] public void TestToTypeReferencePointerType() { - Assert.AreEqual(typeof(int*).FullName, - compilation.FindType(typeof(int*)).ReflectionName); + Assert.That(compilation.FindType(typeof(int*)).ReflectionName, Is.EqualTo(typeof(int*).FullName)); } [Test] public void TestToTypeReferenceByReferenceType() { - Assert.AreEqual(typeof(int).MakeByRefType().FullName, - compilation.FindType(typeof(int).MakeByRefType()).ReflectionName); + Assert.That(compilation.FindType(typeof(int).MakeByRefType()).ReflectionName, Is.EqualTo(typeof(int).MakeByRefType().FullName)); } [Test] @@ -159,43 +146,43 @@ public void TestToTypeReferenceGenericType() ITypeReference parameterType = convertAllInfo.GetParameters()[0].ParameterType.ToTypeReference(); // Converter[[`0],[``0]] // cannot resolve generic types without knowing the parent entity: IType resolvedWithoutEntity = parameterType.Resolve(new SimpleTypeResolveContext(compilation)); - Assert.AreEqual("System.Converter`2[[`0],[``0]]", resolvedWithoutEntity.ReflectionName); - Assert.IsNull(((ITypeParameter)((ParameterizedType)resolvedWithoutEntity).GetTypeArgument(0)).Owner); + Assert.That(resolvedWithoutEntity.ReflectionName, Is.EqualTo("System.Converter`2[[`0],[``0]]")); + Assert.That(((ITypeParameter)((ParameterizedType)resolvedWithoutEntity).GetTypeArgument(0)).Owner, Is.Null); // now try with parent entity: IMethod convertAll = compilation.FindType(typeof(List<>)).GetMethods(m => m.Name == "ConvertAll").Single(); IType resolvedWithEntity = parameterType.Resolve(new SimpleTypeResolveContext(convertAll)); - Assert.AreEqual("System.Converter`2[[`0],[``0]]", resolvedWithEntity.ReflectionName); - Assert.AreSame(convertAll.DeclaringTypeDefinition, ((ITypeParameter)((ParameterizedType)resolvedWithEntity).GetTypeArgument(0)).Owner); + Assert.That(resolvedWithEntity.ReflectionName, Is.EqualTo("System.Converter`2[[`0],[``0]]")); + Assert.That(((ITypeParameter)((ParameterizedType)resolvedWithEntity).GetTypeArgument(0)).Owner, Is.SameAs(convertAll.DeclaringTypeDefinition)); } [Test] public void ParseReflectionName() { var context = new SimpleTypeResolveContext(compilation.MainModule); - Assert.AreEqual("System.Int32", ReflectionHelper.ParseReflectionName("System.Int32").Resolve(context).ReflectionName); - Assert.AreEqual("System.Int32&", ReflectionHelper.ParseReflectionName("System.Int32&").Resolve(context).ReflectionName); - Assert.AreEqual("System.Int32*&", ReflectionHelper.ParseReflectionName("System.Int32*&").Resolve(context).ReflectionName); - Assert.AreEqual("System.Int32", ReflectionHelper.ParseReflectionName(typeof(int).AssemblyQualifiedName).Resolve(context).ReflectionName); - Assert.AreEqual("System.Action`1[[System.String]]", ReflectionHelper.ParseReflectionName("System.Action`1[[System.String]]").Resolve(context).ReflectionName); - Assert.AreEqual("System.Action`1[[System.String]]", ReflectionHelper.ParseReflectionName("System.Action`1[[System.String, mscorlib]]").Resolve(context).ReflectionName); - Assert.AreEqual("System.Int32[,,][,]", ReflectionHelper.ParseReflectionName(typeof(int[,][,,]).AssemblyQualifiedName).Resolve(context).ReflectionName); - Assert.AreEqual("System.Environment+SpecialFolder", ReflectionHelper.ParseReflectionName("System.Environment+SpecialFolder").Resolve(context).ReflectionName); + Assert.That(ReflectionHelper.ParseReflectionName("System.Int32").Resolve(context).ReflectionName, Is.EqualTo("System.Int32")); + Assert.That(ReflectionHelper.ParseReflectionName("System.Int32&").Resolve(context).ReflectionName, Is.EqualTo("System.Int32&")); + Assert.That(ReflectionHelper.ParseReflectionName("System.Int32*&").Resolve(context).ReflectionName, Is.EqualTo("System.Int32*&")); + Assert.That(ReflectionHelper.ParseReflectionName(typeof(int).AssemblyQualifiedName).Resolve(context).ReflectionName, Is.EqualTo("System.Int32")); + Assert.That(ReflectionHelper.ParseReflectionName("System.Action`1[[System.String]]").Resolve(context).ReflectionName, Is.EqualTo("System.Action`1[[System.String]]")); + Assert.That(ReflectionHelper.ParseReflectionName("System.Action`1[[System.String, mscorlib]]").Resolve(context).ReflectionName, Is.EqualTo("System.Action`1[[System.String]]")); + Assert.That(ReflectionHelper.ParseReflectionName(typeof(int[,][,,]).AssemblyQualifiedName).Resolve(context).ReflectionName, Is.EqualTo("System.Int32[,,][,]")); + Assert.That(ReflectionHelper.ParseReflectionName("System.Environment+SpecialFolder").Resolve(context).ReflectionName, Is.EqualTo("System.Environment+SpecialFolder")); } [Test] public void ParseOpenGenericReflectionName() { ITypeReference typeRef = ReflectionHelper.ParseReflectionName("System.Converter`2[[`0],[``0]]"); - Assert.AreEqual("System.Converter`2[[`0],[``0]]", typeRef.Resolve(new SimpleTypeResolveContext(compilation.MainModule)).ReflectionName); + Assert.That(typeRef.Resolve(new SimpleTypeResolveContext(compilation.MainModule)).ReflectionName, Is.EqualTo("System.Converter`2[[`0],[``0]]")); IMethod convertAll = compilation.FindType(typeof(List<>)).GetMethods(m => m.Name == "ConvertAll").Single(); - Assert.AreEqual("System.Converter`2[[`0],[``0]]", typeRef.Resolve(new SimpleTypeResolveContext(convertAll)).ReflectionName); + Assert.That(typeRef.Resolve(new SimpleTypeResolveContext(convertAll)).ReflectionName, Is.EqualTo("System.Converter`2[[`0],[``0]]")); } [Test] public void ArrayOfTypeParameter() { var context = new SimpleTypeResolveContext(compilation.MainModule); - Assert.AreEqual("`0[,]", ReflectionHelper.ParseReflectionName("`0[,]").Resolve(context).ReflectionName); + Assert.That(ReflectionHelper.ParseReflectionName("`0[,]").Resolve(context).ReflectionName, Is.EqualTo("`0[,]")); } [Test] diff --git a/ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemLoaderTests.cs b/ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemLoaderTests.cs index b6346f0fde..b27a1ecc5c 100644 --- a/ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemLoaderTests.cs +++ b/ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemLoaderTests.cs @@ -29,6 +29,7 @@ using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem.Implementation; +using ICSharpCode.Decompiler.Util; using NUnit.Framework; @@ -81,16 +82,16 @@ protected ITypeDefinition GetTypeDefinition(Type type) public void SimplePublicClassTest() { ITypeDefinition c = GetTypeDefinition(typeof(SimplePublicClass)); - Assert.AreEqual(typeof(SimplePublicClass).Name, c.Name); - Assert.AreEqual(typeof(SimplePublicClass).FullName, c.FullName); - Assert.AreEqual(typeof(SimplePublicClass).Namespace, c.Namespace); - Assert.AreEqual(typeof(SimplePublicClass).FullName, c.ReflectionName); + Assert.That(c.Name, Is.EqualTo(typeof(SimplePublicClass).Name)); + Assert.That(c.FullName, Is.EqualTo(typeof(SimplePublicClass).FullName)); + Assert.That(c.Namespace, Is.EqualTo(typeof(SimplePublicClass).Namespace)); + Assert.That(c.ReflectionName, Is.EqualTo(typeof(SimplePublicClass).FullName)); - Assert.AreEqual(Accessibility.Public, c.Accessibility); - Assert.IsFalse(c.IsAbstract); - Assert.IsFalse(c.IsSealed); - Assert.IsFalse(c.IsStatic); - Assert.IsFalse(c.HasAttribute(KnownAttribute.SpecialName)); + Assert.That(c.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(!c.IsAbstract); + Assert.That(!c.IsSealed); + Assert.That(!c.IsStatic); + Assert.That(!c.HasAttribute(KnownAttribute.SpecialName)); } [Test] @@ -99,17 +100,17 @@ public void SimplePublicClassMethodTest() ITypeDefinition c = GetTypeDefinition(typeof(SimplePublicClass)); IMethod method = c.Methods.Single(m => m.Name == "Method"); - Assert.AreEqual(typeof(SimplePublicClass).FullName + ".Method", method.FullName); - Assert.AreSame(c, method.DeclaringType); - Assert.AreEqual(Accessibility.Public, method.Accessibility); - Assert.AreEqual(SymbolKind.Method, method.SymbolKind); - Assert.IsFalse(method.IsVirtual); - Assert.IsFalse(method.IsStatic); - Assert.AreEqual(0, method.Parameters.Count); - Assert.AreEqual(0, method.GetAttributes().Count()); - Assert.IsTrue(method.HasBody); - Assert.IsNull(method.AccessorOwner); - Assert.IsFalse(method.HasAttribute(KnownAttribute.SpecialName)); + Assert.That(method.FullName, Is.EqualTo(typeof(SimplePublicClass).FullName + ".Method")); + Assert.That(method.DeclaringType, Is.SameAs(c)); + Assert.That(method.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(method.SymbolKind, Is.EqualTo(SymbolKind.Method)); + Assert.That(!method.IsVirtual); + Assert.That(!method.IsStatic); + Assert.That(method.Parameters.Count, Is.EqualTo(0)); + Assert.That(method.GetAttributes().Count(), Is.EqualTo(0)); + Assert.That(method.HasBody); + Assert.That(method.AccessorOwner, Is.Null); + Assert.That(!method.HasAttribute(KnownAttribute.SpecialName)); } [Test] @@ -118,17 +119,17 @@ public void SimplePublicClassCtorTest() ITypeDefinition c = GetTypeDefinition(typeof(SimplePublicClass)); IMethod method = c.Methods.Single(m => m.IsConstructor); - Assert.AreEqual(typeof(SimplePublicClass).FullName + "..ctor", method.FullName); - Assert.AreSame(c, method.DeclaringType); - Assert.AreEqual(Accessibility.Public, method.Accessibility); - Assert.AreEqual(SymbolKind.Constructor, method.SymbolKind); - Assert.IsFalse(method.IsVirtual); - Assert.IsFalse(method.IsStatic); - Assert.AreEqual(0, method.Parameters.Count); - Assert.AreEqual(0, method.GetAttributes().Count()); - Assert.IsTrue(method.HasBody); - Assert.IsNull(method.AccessorOwner); - Assert.IsFalse(method.HasAttribute(KnownAttribute.SpecialName)); + Assert.That(method.FullName, Is.EqualTo(typeof(SimplePublicClass).FullName + "..ctor")); + Assert.That(method.DeclaringType, Is.SameAs(c)); + Assert.That(method.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(method.SymbolKind, Is.EqualTo(SymbolKind.Constructor)); + Assert.That(!method.IsVirtual); + Assert.That(!method.IsStatic); + Assert.That(method.Parameters.Count, Is.EqualTo(0)); + Assert.That(method.GetAttributes().Count(), Is.EqualTo(0)); + Assert.That(method.HasBody); + Assert.That(method.AccessorOwner, Is.Null); + Assert.That(!method.HasAttribute(KnownAttribute.SpecialName)); } [Test] @@ -137,26 +138,26 @@ public void SimplePublicClassDtorTest() ITypeDefinition c = GetTypeDefinition(typeof(SimplePublicClass)); IMethod method = c.Methods.Single(m => m.IsDestructor); - Assert.AreEqual(typeof(SimplePublicClass).FullName + ".Finalize", method.FullName); - Assert.AreSame(c, method.DeclaringType); - Assert.AreEqual(Accessibility.Protected, method.Accessibility); - Assert.AreEqual(SymbolKind.Destructor, method.SymbolKind); - Assert.IsFalse(method.IsVirtual); - Assert.IsFalse(method.IsStatic); - Assert.AreEqual(0, method.Parameters.Count); - Assert.AreEqual(1, method.GetAttributes().Count()); - Assert.IsTrue(method.HasBody); - Assert.IsNull(method.AccessorOwner); - Assert.IsFalse(method.HasAttribute(KnownAttribute.SpecialName)); + Assert.That(method.FullName, Is.EqualTo(typeof(SimplePublicClass).FullName + ".Finalize")); + Assert.That(method.DeclaringType, Is.SameAs(c)); + Assert.That(method.Accessibility, Is.EqualTo(Accessibility.Protected)); + Assert.That(method.SymbolKind, Is.EqualTo(SymbolKind.Destructor)); + Assert.That(!method.IsVirtual); + Assert.That(!method.IsStatic); + Assert.That(method.Parameters.Count, Is.EqualTo(0)); + Assert.That(method.GetAttributes().Count(), Is.EqualTo(1)); + Assert.That(method.HasBody); + Assert.That(method.AccessorOwner, Is.Null); + Assert.That(!method.HasAttribute(KnownAttribute.SpecialName)); } [Test] public void DynamicType() { ITypeDefinition testClass = GetTypeDefinition(typeof(DynamicTest)); - Assert.AreEqual(SpecialType.Dynamic, testClass.Fields.Single(f => f.Name == "DynamicField").ReturnType); - Assert.AreEqual(SpecialType.Dynamic, testClass.Properties.Single().ReturnType); - Assert.AreEqual(0, testClass.Properties.Single().GetAttributes().Count()); + Assert.That(testClass.Fields.Single(f => f.Name == "DynamicField").ReturnType, Is.EqualTo(SpecialType.Dynamic)); + Assert.That(testClass.Properties.Single().ReturnType, Is.EqualTo(SpecialType.Dynamic)); + Assert.That(testClass.Properties.Single().GetAttributes().Count(), Is.EqualTo(0)); } [Test] @@ -165,26 +166,26 @@ public void DynamicTypeInGenerics() ITypeDefinition testClass = GetTypeDefinition(typeof(DynamicTest)); IMethod m1 = testClass.Methods.Single(me => me.Name == "DynamicGenerics1"); - Assert.AreEqual("System.Collections.Generic.List`1[[dynamic]]", m1.ReturnType.ReflectionName); - Assert.AreEqual("System.Action`3[[System.Object],[dynamic[]],[System.Object]]", m1.Parameters[0].Type.ReflectionName); + Assert.That(m1.ReturnType.ReflectionName, Is.EqualTo("System.Collections.Generic.List`1[[dynamic]]")); + Assert.That(m1.Parameters[0].Type.ReflectionName, Is.EqualTo("System.Action`3[[System.Object],[dynamic[]],[System.Object]]")); IMethod m2 = testClass.Methods.Single(me => me.Name == "DynamicGenerics2"); - Assert.AreEqual("System.Action`3[[System.Object],[dynamic],[System.Object]]", m2.Parameters[0].Type.ReflectionName); + Assert.That(m2.Parameters[0].Type.ReflectionName, Is.EqualTo("System.Action`3[[System.Object],[dynamic],[System.Object]]")); IMethod m3 = testClass.Methods.Single(me => me.Name == "DynamicGenerics3"); - Assert.AreEqual("System.Action`3[[System.Int32],[dynamic],[System.Object]]", m3.Parameters[0].Type.ReflectionName); + Assert.That(m3.Parameters[0].Type.ReflectionName, Is.EqualTo("System.Action`3[[System.Int32],[dynamic],[System.Object]]")); IMethod m4 = testClass.Methods.Single(me => me.Name == "DynamicGenerics4"); - Assert.AreEqual("System.Action`3[[System.Int32[]],[dynamic],[System.Object]]", m4.Parameters[0].Type.ReflectionName); + Assert.That(m4.Parameters[0].Type.ReflectionName, Is.EqualTo("System.Action`3[[System.Int32[]],[dynamic],[System.Object]]")); IMethod m5 = testClass.Methods.Single(me => me.Name == "DynamicGenerics5"); - Assert.AreEqual("System.Action`3[[System.Int32*[]],[dynamic],[System.Object]]", m5.Parameters[0].Type.ReflectionName); + Assert.That(m5.Parameters[0].Type.ReflectionName, Is.EqualTo("System.Action`3[[System.Int32*[]],[dynamic],[System.Object]]")); IMethod m6 = testClass.Methods.Single(me => me.Name == "DynamicGenerics6"); - Assert.AreEqual("System.Action`3[[System.Object],[dynamic],[System.Object]]&", m6.Parameters[0].Type.ReflectionName); + Assert.That(m6.Parameters[0].Type.ReflectionName, Is.EqualTo("System.Action`3[[System.Object],[dynamic],[System.Object]]&")); IMethod m7 = testClass.Methods.Single(me => me.Name == "DynamicGenerics7"); - Assert.AreEqual("System.Action`3[[System.Int32[][,]],[dynamic],[System.Object]]", m7.Parameters[0].Type.ReflectionName); + Assert.That(m7.Parameters[0].Type.ReflectionName, Is.EqualTo("System.Action`3[[System.Int32[][,]],[dynamic],[System.Object]]")); } [Test] @@ -192,7 +193,7 @@ public void DynamicParameterHasNoAttributes() { ITypeDefinition testClass = GetTypeDefinition(typeof(DynamicTest)); IMethod m1 = testClass.Methods.Single(me => me.Name == "DynamicGenerics1"); - Assert.AreEqual(0, m1.Parameters[0].GetAttributes().Count()); + Assert.That(m1.Parameters[0].GetAttributes().Count(), Is.EqualTo(0)); } [Test] @@ -200,23 +201,23 @@ public void AssemblyAttribute() { var attributes = compilation.MainModule.GetAssemblyAttributes().ToList(); var typeTest = attributes.Single(a => a.AttributeType.FullName == typeof(TypeTestAttribute).FullName); - Assert.AreEqual(3, typeTest.FixedArguments.Length); + Assert.That(typeTest.FixedArguments.Length, Is.EqualTo(3)); // first argument is (int)42 - Assert.AreEqual(42, (int)typeTest.FixedArguments[0].Value); + Assert.That((int)typeTest.FixedArguments[0].Value, Is.EqualTo(42)); // second argument is typeof(System.Action<>) var ty = (IType)typeTest.FixedArguments[1].Value; - Assert.IsFalse(ty is ParameterizedType); // rt must not be constructed - it's just an unbound type - Assert.AreEqual("System.Action", ty.FullName); - Assert.AreEqual(1, ty.TypeParameterCount); + Assert.That(ty is ParameterizedType, Is.False); // rt must not be constructed - it's just an unbound type + Assert.That(ty.FullName, Is.EqualTo("System.Action")); + Assert.That(ty.TypeParameterCount, Is.EqualTo(1)); // third argument is typeof(IDictionary>) var crt = (ParameterizedType)typeTest.FixedArguments[2].Value; - Assert.AreEqual("System.Collections.Generic.IDictionary", crt.FullName); - Assert.AreEqual("System.String", crt.TypeArguments[0].FullName); + Assert.That(crt.FullName, Is.EqualTo("System.Collections.Generic.IDictionary")); + Assert.That(crt.TypeArguments[0].FullName, Is.EqualTo("System.String")); // we know the name for TestAttribute, but not necessarily the namespace, as NUnit is not in the compilation - Assert.AreEqual("System.Collections.Generic.IList", crt.TypeArguments[1].FullName); + Assert.That(crt.TypeArguments[1].FullName, Is.EqualTo("System.Collections.Generic.IList")); var testAttributeType = ((ParameterizedType)crt.TypeArguments[1]).TypeArguments.Single(); - Assert.AreEqual("TestAttribute", testAttributeType.Name); - Assert.AreEqual(TypeKind.Unknown, testAttributeType.Kind); + Assert.That(testAttributeType.Name, Is.EqualTo("TestAttribute")); + Assert.That(testAttributeType.Kind, Is.EqualTo(TypeKind.Unknown)); // (more accurately, we know the namespace and reflection name if the type was loaded by cecil, // but not if we parsed it from C#) } @@ -226,18 +227,18 @@ public void TypeForwardedTo_Attribute() { var attributes = compilation.MainModule.GetAssemblyAttributes().ToList(); var forwardAttribute = attributes.Single(a => a.AttributeType.FullName == typeof(TypeForwardedToAttribute).FullName); - Assert.AreEqual(1, forwardAttribute.FixedArguments.Length); + Assert.That(forwardAttribute.FixedArguments.Length, Is.EqualTo(1)); var rt = (IType)forwardAttribute.FixedArguments[0].Value; - Assert.AreEqual("System.Func`2", rt.ReflectionName); + Assert.That(rt.ReflectionName, Is.EqualTo("System.Func`2")); } [Test] public void TestClassTypeParameters() { var testClass = GetTypeDefinition(typeof(GenericClass<,>)); - Assert.AreEqual(SymbolKind.TypeDefinition, testClass.TypeParameters[0].OwnerType); - Assert.AreEqual(SymbolKind.TypeDefinition, testClass.TypeParameters[1].OwnerType); - Assert.AreSame(testClass.TypeParameters[1], testClass.TypeParameters[0].DirectBaseTypes.First()); + Assert.That(testClass.TypeParameters[0].OwnerType, Is.EqualTo(SymbolKind.TypeDefinition)); + Assert.That(testClass.TypeParameters[1].OwnerType, Is.EqualTo(SymbolKind.TypeDefinition)); + Assert.That(testClass.TypeParameters[0].DirectBaseTypes.First(), Is.SameAs(testClass.TypeParameters[1])); } [Test] @@ -246,13 +247,13 @@ public void TestMethod() var testClass = GetTypeDefinition(typeof(GenericClass<,>)); IMethod m = testClass.Methods.Single(me => me.Name == "TestMethod"); - Assert.AreEqual("K", m.TypeParameters[0].Name); - Assert.AreEqual("V", m.TypeParameters[1].Name); - Assert.AreEqual(SymbolKind.Method, m.TypeParameters[0].OwnerType); - Assert.AreEqual(SymbolKind.Method, m.TypeParameters[1].OwnerType); + Assert.That(m.TypeParameters[0].Name, Is.EqualTo("K")); + Assert.That(m.TypeParameters[1].Name, Is.EqualTo("V")); + Assert.That(m.TypeParameters[0].OwnerType, Is.EqualTo(SymbolKind.Method)); + Assert.That(m.TypeParameters[1].OwnerType, Is.EqualTo(SymbolKind.Method)); - Assert.AreEqual("System.IComparable`1[[``1]]", m.TypeParameters[0].DirectBaseTypes.First().ReflectionName); - Assert.AreSame(m.TypeParameters[0], m.TypeParameters[1].DirectBaseTypes.First()); + Assert.That(m.TypeParameters[0].DirectBaseTypes.First().ReflectionName, Is.EqualTo("System.IComparable`1[[``1]]")); + Assert.That(m.TypeParameters[1].DirectBaseTypes.First(), Is.SameAs(m.TypeParameters[0])); } [Test] @@ -261,16 +262,16 @@ public void GetIndex() var testClass = GetTypeDefinition(typeof(GenericClass<,>)); IMethod m = testClass.Methods.Single(me => me.Name == "GetIndex"); - Assert.AreEqual("T", m.TypeParameters[0].Name); - Assert.AreEqual(SymbolKind.Method, m.TypeParameters[0].OwnerType); - Assert.AreSame(m, m.TypeParameters[0].Owner); + Assert.That(m.TypeParameters[0].Name, Is.EqualTo("T")); + Assert.That(m.TypeParameters[0].OwnerType, Is.EqualTo(SymbolKind.Method)); + Assert.That(m.TypeParameters[0].Owner, Is.SameAs(m)); ParameterizedType constraint = (ParameterizedType)m.TypeParameters[0].DirectBaseTypes.First(); - Assert.AreEqual("IEquatable", constraint.Name); - Assert.AreEqual(1, constraint.TypeParameterCount); - Assert.AreEqual(1, constraint.TypeArguments.Count); - Assert.AreSame(m.TypeParameters[0], constraint.TypeArguments[0]); - Assert.AreSame(m.TypeParameters[0], m.Parameters[0].Type); + Assert.That(constraint.Name, Is.EqualTo("IEquatable")); + Assert.That(constraint.TypeParameterCount, Is.EqualTo(1)); + Assert.That(constraint.TypeArguments.Count, Is.EqualTo(1)); + Assert.That(constraint.TypeArguments[0], Is.SameAs(m.TypeParameters[0])); + Assert.That(m.Parameters[0].Type, Is.SameAs(m.TypeParameters[0])); } [Test] @@ -283,16 +284,16 @@ public void GetIndexSpecializedTypeParameter() null )); - Assert.AreEqual("T", m.TypeParameters[0].Name); - Assert.AreEqual(SymbolKind.Method, m.TypeParameters[0].OwnerType); - Assert.AreSame(m, m.TypeParameters[0].Owner); + Assert.That(m.TypeParameters[0].Name, Is.EqualTo("T")); + Assert.That(m.TypeParameters[0].OwnerType, Is.EqualTo(SymbolKind.Method)); + Assert.That(m.TypeParameters[0].Owner, Is.SameAs(m)); ParameterizedType constraint = (ParameterizedType)m.TypeParameters[0].DirectBaseTypes.First(); - Assert.AreEqual("IEquatable", constraint.Name); - Assert.AreEqual(1, constraint.TypeParameterCount); - Assert.AreEqual(1, constraint.TypeArguments.Count); - Assert.AreSame(m.TypeParameters[0], constraint.TypeArguments[0]); - Assert.AreSame(m.TypeParameters[0], m.Parameters[0].Type); + Assert.That(constraint.Name, Is.EqualTo("IEquatable")); + Assert.That(constraint.TypeParameterCount, Is.EqualTo(1)); + Assert.That(constraint.TypeArguments.Count, Is.EqualTo(1)); + Assert.That(constraint.TypeArguments[0], Is.SameAs(m.TypeParameters[0])); + Assert.That(m.Parameters[0].Type, Is.SameAs(m.TypeParameters[0])); } [Test] @@ -318,7 +319,7 @@ public void GetIndexDoubleSpecialization() new[] { compilation.FindType(KnownTypeCode.String), compilation.FindType(KnownTypeCode.Int32) }, new[] { compilation.FindType(KnownTypeCode.Int32) } )); - Assert.AreEqual(m12, m2); + Assert.That(m2, Is.EqualTo(m12)); } [Test] @@ -326,18 +327,18 @@ public void SpecializedMethod_AccessorOwner() { // NRefactory bug #143 - Accessor Owner throws null reference exception in some cases now var method = compilation.FindType(typeof(GenericClass)).GetMethods(m => m.Name == "GetIndex").Single(); - Assert.IsNull(method.AccessorOwner); + Assert.That(method.AccessorOwner, Is.Null); } [Test] public void Specialized_GetIndex_ToMemberReference() { var method = compilation.FindType(typeof(GenericClass)).GetMethods(m => m.Name == "GetIndex").Single(); - Assert.AreSame(method.TypeParameters[0], method.Parameters[0].Type); - Assert.AreSame(method, method.TypeParameters[0].Owner); - Assert.IsInstanceOf(method); - //Assert.IsFalse(method.IsParameterized); // the method itself is not specialized - Assert.AreEqual(method.TypeParameters, method.TypeArguments); + Assert.That(method.Parameters[0].Type, Is.SameAs(method.TypeParameters[0])); + Assert.That(method.TypeParameters[0].Owner, Is.SameAs(method)); + Assert.That(method, Is.InstanceOf()); + //Assert.That(!method.IsParameterized); // the method itself is not specialized + Assert.That(method.TypeArguments, Is.EqualTo(method.TypeParameters)); } [Test] @@ -347,23 +348,23 @@ public void Specialized_GetIndex_SpecializeWithIdentityHasNoEffect() IType[] methodTypeArguments = { DummyTypeParameter.GetMethodTypeParameter(0) }; var method = genericClass.GetMethods(methodTypeArguments, m => m.Name == "GetIndex").Single(); // GenericClass.GetIndex() - Assert.AreSame(method, method.TypeParameters[0].Owner); - Assert.AreNotEqual(method.TypeParameters[0], method.TypeArguments[0]); - Assert.IsNull(((ITypeParameter)method.TypeArguments[0]).Owner); + Assert.That(method.TypeParameters[0].Owner, Is.SameAs(method)); + Assert.That(method.TypeArguments[0], Is.Not.EqualTo(method.TypeParameters[0])); + Assert.That(((ITypeParameter)method.TypeArguments[0]).Owner, Is.Null); // Now apply identity substitution: var method2 = method.Specialize(TypeParameterSubstitution.Identity); - Assert.AreSame(method2, method2.TypeParameters[0].Owner); - Assert.AreNotEqual(method2.TypeParameters[0], method2.TypeArguments[0]); - Assert.IsNull(((ITypeParameter)method2.TypeArguments[0]).Owner); + Assert.That(method2.TypeParameters[0].Owner, Is.SameAs(method2)); + Assert.That(method2.TypeArguments[0], Is.Not.EqualTo(method2.TypeParameters[0])); + Assert.That(((ITypeParameter)method2.TypeArguments[0]).Owner, Is.Null); - Assert.AreEqual(method, method2); + Assert.That(method2, Is.EqualTo(method)); } [Test] public void GenericEnum() { var testClass = GetTypeDefinition(typeof(GenericClass<,>.NestedEnum)); - Assert.AreEqual(2, testClass.TypeParameterCount); + Assert.That(testClass.TypeParameterCount, Is.EqualTo(2)); } [Test] @@ -372,7 +373,7 @@ public void FieldInGenericClassWithNestedEnumType() var testClass = GetTypeDefinition(typeof(GenericClass<,>)); var enumClass = GetTypeDefinition(typeof(GenericClass<,>.NestedEnum)); var field = testClass.Fields.Single(f => f.Name == "EnumField"); - Assert.AreEqual(new ParameterizedType(enumClass, testClass.TypeParameters), field.ReturnType); + Assert.That(field.ReturnType, Is.EqualTo(new ParameterizedType(enumClass, testClass.TypeParameters))); } [Test] @@ -380,7 +381,7 @@ public void GenericEnumMemberReturnType() { var enumClass = GetTypeDefinition(typeof(GenericClass<,>.NestedEnum)); var field = enumClass.Fields.Single(f => f.Name == "EnumMember"); - Assert.AreEqual(new ParameterizedType(enumClass, enumClass.TypeParameters), field.ReturnType); + Assert.That(field.ReturnType, Is.EqualTo(new ParameterizedType(enumClass, enumClass.TypeParameters))); } [Test] @@ -388,11 +389,11 @@ public void PropertyWithProtectedSetter() { var testClass = GetTypeDefinition(typeof(PropertyTest)); IProperty p = testClass.Properties.Single(pr => pr.Name == "PropertyWithProtectedSetter"); - Assert.IsTrue(p.CanGet); - Assert.IsTrue(p.CanSet); - Assert.AreEqual(Accessibility.Public, p.Accessibility); - Assert.AreEqual(Accessibility.Public, p.Getter.Accessibility); - Assert.AreEqual(Accessibility.Protected, p.Setter.Accessibility); + Assert.That(p.CanGet); + Assert.That(p.CanSet); + Assert.That(p.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(p.Getter.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(p.Setter.Accessibility, Is.EqualTo(Accessibility.Protected)); } [Test] @@ -400,15 +401,15 @@ public void PropertyWithPrivateSetter() { var testClass = GetTypeDefinition(typeof(PropertyTest)); IProperty p = testClass.Properties.Single(pr => pr.Name == "PropertyWithPrivateSetter"); - Assert.IsTrue(p.CanGet); - Assert.IsTrue(p.CanSet); - Assert.AreEqual(Accessibility.Public, p.Accessibility); - Assert.AreEqual(Accessibility.Public, p.Getter.Accessibility); - Assert.AreEqual(Accessibility.Private, p.Setter.Accessibility); - Assert.IsTrue(p.Getter.HasBody); - Assert.IsFalse(p.HasAttribute(KnownAttribute.SpecialName)); - Assert.IsFalse(p.Getter.HasAttribute(KnownAttribute.SpecialName)); - Assert.IsFalse(p.Setter.HasAttribute(KnownAttribute.SpecialName)); + Assert.That(p.CanGet); + Assert.That(p.CanSet); + Assert.That(p.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(p.Getter.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(p.Setter.Accessibility, Is.EqualTo(Accessibility.Private)); + Assert.That(p.Getter.HasBody); + Assert.That(!p.HasAttribute(KnownAttribute.SpecialName)); + Assert.That(!p.Getter.HasAttribute(KnownAttribute.SpecialName)); + Assert.That(!p.Setter.HasAttribute(KnownAttribute.SpecialName)); } [Test] @@ -416,12 +417,12 @@ public void PropertyWithPrivateGetter() { var testClass = GetTypeDefinition(typeof(PropertyTest)); IProperty p = testClass.Properties.Single(pr => pr.Name == "PropertyWithPrivateGetter"); - Assert.IsTrue(p.CanGet); - Assert.IsTrue(p.CanSet); - Assert.AreEqual(Accessibility.Public, p.Accessibility); - Assert.AreEqual(Accessibility.Private, p.Getter.Accessibility); - Assert.AreEqual(Accessibility.Public, p.Setter.Accessibility); - Assert.IsTrue(p.Getter.HasBody); + Assert.That(p.CanGet); + Assert.That(p.CanSet); + Assert.That(p.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(p.Getter.Accessibility, Is.EqualTo(Accessibility.Private)); + Assert.That(p.Setter.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(p.Getter.HasBody); } [Test] @@ -429,11 +430,11 @@ public void PropertyWithoutSetter() { var testClass = GetTypeDefinition(typeof(PropertyTest)); IProperty p = testClass.Properties.Single(pr => pr.Name == "PropertyWithoutSetter"); - Assert.IsTrue(p.CanGet); - Assert.IsFalse(p.CanSet); - Assert.AreEqual(Accessibility.Public, p.Accessibility); - Assert.AreEqual(Accessibility.Public, p.Getter.Accessibility); - Assert.IsNull(p.Setter); + Assert.That(p.CanGet); + Assert.That(!p.CanSet); + Assert.That(p.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(p.Getter.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(p.Setter, Is.Null); } [Test] @@ -441,8 +442,8 @@ public void Indexer() { var testClass = GetTypeDefinition(typeof(PropertyTest)); IProperty p = testClass.Properties.Single(pr => pr.IsIndexer); - Assert.AreEqual("Item", p.Name); - Assert.AreEqual(new[] { "index" }, p.Parameters.Select(x => x.Name).ToArray()); + Assert.That(p.Name, Is.EqualTo("Item")); + Assert.That(p.Parameters.Select(x => x.Name).ToArray(), Is.EqualTo(new[] { "index" })); } [Test] @@ -450,13 +451,13 @@ public void IndexerGetter() { var testClass = GetTypeDefinition(typeof(PropertyTest)); IProperty p = testClass.Properties.Single(pr => pr.IsIndexer); - Assert.IsTrue(p.CanGet); - Assert.AreEqual(SymbolKind.Accessor, p.Getter.SymbolKind); - Assert.AreEqual("get_Item", p.Getter.Name); - Assert.AreEqual(Accessibility.Public, p.Getter.Accessibility); - Assert.AreEqual(new[] { "index" }, p.Getter.Parameters.Select(x => x.Name).ToArray()); - Assert.AreEqual("System.String", p.Getter.ReturnType.ReflectionName); - Assert.AreEqual(p, p.Getter.AccessorOwner); + Assert.That(p.CanGet); + Assert.That(p.Getter.SymbolKind, Is.EqualTo(SymbolKind.Accessor)); + Assert.That(p.Getter.Name, Is.EqualTo("get_Item")); + Assert.That(p.Getter.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(p.Getter.Parameters.Select(x => x.Name).ToArray(), Is.EqualTo(new[] { "index" })); + Assert.That(p.Getter.ReturnType.ReflectionName, Is.EqualTo("System.String")); + Assert.That(p.Getter.AccessorOwner, Is.EqualTo(p)); } [Test] @@ -464,12 +465,12 @@ public void IndexerSetter() { var testClass = GetTypeDefinition(typeof(PropertyTest)); IProperty p = testClass.Properties.Single(pr => pr.IsIndexer); - Assert.IsTrue(p.CanSet); - Assert.AreEqual(SymbolKind.Accessor, p.Setter.SymbolKind); - Assert.AreEqual("set_Item", p.Setter.Name); - Assert.AreEqual(Accessibility.Public, p.Setter.Accessibility); - Assert.AreEqual(new[] { "index", "value" }, p.Setter.Parameters.Select(x => x.Name).ToArray()); - Assert.AreEqual(TypeKind.Void, p.Setter.ReturnType.Kind); + Assert.That(p.CanSet); + Assert.That(p.Setter.SymbolKind, Is.EqualTo(SymbolKind.Accessor)); + Assert.That(p.Setter.Name, Is.EqualTo("set_Item")); + Assert.That(p.Setter.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(p.Setter.Parameters.Select(x => x.Name).ToArray(), Is.EqualTo(new[] { "index", "value" })); + Assert.That(p.Setter.ReturnType.Kind, Is.EqualTo(TypeKind.Void)); } [Test] @@ -477,19 +478,19 @@ public void GenericPropertyGetter() { var type = compilation.FindType(typeof(GenericClass)); var prop = type.GetProperties(p => p.Name == "Property").Single(); - Assert.AreEqual("System.String", prop.Getter.ReturnType.ReflectionName); - Assert.IsTrue(prop.Getter.IsAccessor); - Assert.AreEqual(prop, prop.Getter.AccessorOwner); + Assert.That(prop.Getter.ReturnType.ReflectionName, Is.EqualTo("System.String")); + Assert.That(prop.Getter.IsAccessor); + Assert.That(prop.Getter.AccessorOwner, Is.EqualTo(prop)); } [Test] public void EnumTest() { var e = GetTypeDefinition(typeof(MyEnum)); - Assert.AreEqual(TypeKind.Enum, e.Kind); - Assert.AreEqual(false, e.IsReferenceType); - Assert.AreEqual("System.Int16", e.EnumUnderlyingType.ReflectionName); - Assert.AreEqual(new[] { "System.Enum" }, e.DirectBaseTypes.Select(t => t.ReflectionName).ToArray()); + Assert.That(e.Kind, Is.EqualTo(TypeKind.Enum)); + Assert.That(e.IsReferenceType, Is.EqualTo(false)); + Assert.That(e.EnumUnderlyingType.ReflectionName, Is.EqualTo("System.Int16")); + Assert.That(e.DirectBaseTypes.Select(t => t.ReflectionName).ToArray(), Is.EqualTo(new[] { "System.Enum" })); } [Test] @@ -498,39 +499,39 @@ public void EnumFieldsTest() var e = GetTypeDefinition(typeof(MyEnum)); IField valueField = e.Fields.First(); IField[] fields = e.Fields.Skip(1).ToArray(); - Assert.AreEqual(5, fields.Length); + Assert.That(fields.Length, Is.EqualTo(5)); - Assert.AreEqual("value__", valueField.Name); - Assert.AreEqual(GetTypeDefinition(typeof(short)), valueField.Type); - Assert.AreEqual(Accessibility.Public, valueField.Accessibility); - Assert.AreEqual(null, valueField.GetConstantValue()); - Assert.IsFalse(valueField.IsConst); - Assert.IsFalse(valueField.IsStatic); + Assert.That(valueField.Name, Is.EqualTo("value__")); + Assert.That(valueField.Type, Is.EqualTo(GetTypeDefinition(typeof(short)))); + Assert.That(valueField.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(valueField.GetConstantValue(), Is.EqualTo(null)); + Assert.That(!valueField.IsConst); + Assert.That(!valueField.IsStatic); foreach (IField f in fields) { - Assert.IsTrue(f.IsStatic); - Assert.IsTrue(f.IsConst); - Assert.AreEqual(Accessibility.Public, f.Accessibility); - Assert.AreSame(e, f.Type); - Assert.AreEqual(typeof(short), f.GetConstantValue().GetType()); + Assert.That(f.IsStatic); + Assert.That(f.IsConst); + Assert.That(f.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(f.Type, Is.SameAs(e)); + Assert.That(f.GetConstantValue().GetType(), Is.EqualTo(typeof(short))); } - Assert.AreEqual("First", fields[0].Name); - Assert.AreEqual(0, fields[0].GetConstantValue()); + Assert.That(fields[0].Name, Is.EqualTo("First")); + Assert.That(fields[0].GetConstantValue(), Is.EqualTo(0)); - Assert.AreEqual("Second", fields[1].Name); - Assert.AreSame(e, fields[1].Type); - Assert.AreEqual(1, fields[1].GetConstantValue()); + Assert.That(fields[1].Name, Is.EqualTo("Second")); + Assert.That(fields[1].Type, Is.SameAs(e)); + Assert.That(fields[1].GetConstantValue(), Is.EqualTo(1)); - Assert.AreEqual("Flag1", fields[2].Name); - Assert.AreEqual(0x10, fields[2].GetConstantValue()); + Assert.That(fields[2].Name, Is.EqualTo("Flag1")); + Assert.That(fields[2].GetConstantValue(), Is.EqualTo(0x10)); - Assert.AreEqual("Flag2", fields[3].Name); - Assert.AreEqual(0x20, fields[3].GetConstantValue()); + Assert.That(fields[3].Name, Is.EqualTo("Flag2")); + Assert.That(fields[3].GetConstantValue(), Is.EqualTo(0x20)); - Assert.AreEqual("CombinedFlags", fields[4].Name); - Assert.AreEqual(0x30, fields[4].GetConstantValue()); + Assert.That(fields[4].Name, Is.EqualTo("CombinedFlags")); + Assert.That(fields[4].GetConstantValue(), Is.EqualTo(0x30)); } [Test] @@ -539,14 +540,12 @@ public void GetNestedTypesFromBaseClassTest() ITypeDefinition d = GetTypeDefinition(typeof(Derived<,>)); IType pBase = d.DirectBaseTypes.Single(); - Assert.AreEqual(typeof(Base<>).FullName + "[[`1]]", pBase.ReflectionName); + Assert.That(pBase.ReflectionName, Is.EqualTo(typeof(Base<>).FullName + "[[`1]]")); // Base[`1].GetNestedTypes() = { Base`1+Nested`1[`1, unbound] } - Assert.AreEqual(new[] { typeof(Base<>.Nested<>).FullName + "[[`1],[]]" }, - pBase.GetNestedTypes().Select(n => n.ReflectionName).ToArray()); + Assert.That(pBase.GetNestedTypes().Select(n => n.ReflectionName).ToArray(), Is.EqualTo(new[] { typeof(Base<>.Nested<>).FullName + "[[`1],[]]" })); // Derived.GetNestedTypes() = { Base`1+Nested`1[`1, unbound] } - Assert.AreEqual(new[] { typeof(Base<>.Nested<>).FullName + "[[`1],[]]" }, - d.GetNestedTypes().Select(n => n.ReflectionName).ToArray()); + Assert.That(d.GetNestedTypes().Select(n => n.ReflectionName).ToArray(), Is.EqualTo(new[] { typeof(Base<>.Nested<>).FullName + "[[`1],[]]" })); // This is 'leaking' the type parameter from B as is usual when retrieving any members from an unbound type. } @@ -555,8 +554,7 @@ public void ParameterizedTypeGetNestedTypesFromBaseClassTest() { // Derived[string,int].GetNestedTypes() = { Base`1+Nested`1[int, unbound] } var d = compilation.FindType(typeof(Derived)); - Assert.AreEqual(new[] { typeof(Base<>.Nested<>).FullName + "[[System.Int32],[]]" }, - d.GetNestedTypes().Select(n => n.ReflectionName).ToArray()); + Assert.That(d.GetNestedTypes().Select(n => n.ReflectionName).ToArray(), Is.EqualTo(new[] { typeof(Base<>.Nested<>).FullName + "[[System.Int32],[]]" })); } [Test] @@ -564,12 +562,11 @@ public void ConstraintsOnOverrideAreInherited() { ITypeDefinition d = GetTypeDefinition(typeof(Derived<,>)); ITypeParameter tp = d.Methods.Single(m => m.Name == "GenericMethodWithConstraints").TypeParameters.Single(); - Assert.AreEqual("Y", tp.Name); - Assert.IsFalse(tp.HasValueTypeConstraint); - Assert.IsFalse(tp.HasReferenceTypeConstraint); - Assert.IsTrue(tp.HasDefaultConstructorConstraint); - Assert.AreEqual(new string[] { "System.Collections.Generic.IComparer`1[[`1]]", "System.Object" }, - tp.DirectBaseTypes.Select(t => t.ReflectionName).ToArray()); + Assert.That(tp.Name, Is.EqualTo("Y")); + Assert.That(!tp.HasValueTypeConstraint); + Assert.That(!tp.HasReferenceTypeConstraint); + Assert.That(tp.HasDefaultConstructorConstraint); + Assert.That(tp.DirectBaseTypes.Select(t => t.ReflectionName).ToArray(), Is.EqualTo(new string[] { "System.Collections.Generic.IComparer`1[[`1]]", "System.Object" })); } [Test] @@ -577,16 +574,16 @@ public void DtorInDerivedClass() { ITypeDefinition c = GetTypeDefinition(typeof(Derived<,>)); IMethod method = c.Methods.Single(m => m.IsDestructor); - Assert.AreEqual(c.FullName + ".Finalize", method.FullName); - Assert.AreSame(c, method.DeclaringType); - Assert.AreEqual(Accessibility.Protected, method.Accessibility); - Assert.AreEqual(SymbolKind.Destructor, method.SymbolKind); - Assert.IsFalse(method.IsVirtual); - Assert.IsFalse(method.IsStatic); - Assert.AreEqual(0, method.Parameters.Count); - Assert.AreEqual(0, method.GetAttributes().Count()); - Assert.IsTrue(method.HasBody); - Assert.IsNull(method.AccessorOwner); + Assert.That(method.FullName, Is.EqualTo(c.FullName + ".Finalize")); + Assert.That(method.DeclaringType, Is.SameAs(c)); + Assert.That(method.Accessibility, Is.EqualTo(Accessibility.Protected)); + Assert.That(method.SymbolKind, Is.EqualTo(SymbolKind.Destructor)); + Assert.That(!method.IsVirtual); + Assert.That(!method.IsStatic); + Assert.That(method.Parameters.Count, Is.EqualTo(0)); + Assert.That(method.GetAttributes().Count(), Is.EqualTo(0)); + Assert.That(method.HasBody); + Assert.That(method.AccessorOwner, Is.Null); } [Test] @@ -594,102 +591,102 @@ public void PrivateFinalizeMethodIsNotADtor() { ITypeDefinition c = GetTypeDefinition(typeof(TypeTestAttribute)); IMethod method = c.Methods.Single(m => m.Name == "Finalize"); - Assert.AreEqual(c.FullName + ".Finalize", method.FullName); - Assert.AreSame(c, method.DeclaringType); - Assert.AreEqual(Accessibility.Private, method.Accessibility); - Assert.AreEqual(SymbolKind.Method, method.SymbolKind); - Assert.IsFalse(method.IsVirtual); - Assert.IsFalse(method.IsStatic); - Assert.AreEqual(0, method.Parameters.Count); - Assert.AreEqual(0, method.GetAttributes().Count()); - Assert.IsTrue(method.HasBody); - Assert.IsNull(method.AccessorOwner); + Assert.That(method.FullName, Is.EqualTo(c.FullName + ".Finalize")); + Assert.That(method.DeclaringType, Is.SameAs(c)); + Assert.That(method.Accessibility, Is.EqualTo(Accessibility.Private)); + Assert.That(method.SymbolKind, Is.EqualTo(SymbolKind.Method)); + Assert.That(!method.IsVirtual); + Assert.That(!method.IsStatic); + Assert.That(method.Parameters.Count, Is.EqualTo(0)); + Assert.That(method.GetAttributes().Count(), Is.EqualTo(0)); + Assert.That(method.HasBody); + Assert.That(method.AccessorOwner, Is.Null); } [Test] public void DefaultConstructorAddedToStruct() { var ctors = compilation.FindType(typeof(MyStructWithCtor)).GetConstructors(); - Assert.AreEqual(2, ctors.Count()); - Assert.IsFalse(ctors.Any(c => c.IsStatic)); - Assert.IsTrue(ctors.All(c => c.ReturnType.Kind == TypeKind.Void)); - Assert.IsTrue(ctors.All(c => c.Accessibility == Accessibility.Public)); + Assert.That(ctors.Count(), Is.EqualTo(2)); + Assert.That(!ctors.Any(c => c.IsStatic)); + Assert.That(ctors.All(c => c.ReturnType.Kind == TypeKind.Void)); + Assert.That(ctors.All(c => c.Accessibility == Accessibility.Public)); } [Test] public void NoDefaultConstructorAddedToStruct() { var ctors = compilation.FindType(typeof(MyStructWithDefaultCtor)).GetConstructors(); - Assert.AreEqual(1, ctors.Count()); - Assert.IsFalse(ctors.Any(c => c.IsStatic)); - Assert.IsTrue(ctors.All(c => c.ReturnType.Kind == TypeKind.Void)); - Assert.IsTrue(ctors.All(c => c.Accessibility == Accessibility.Public)); + Assert.That(ctors.Count(), Is.EqualTo(1)); + Assert.That(!ctors.Any(c => c.IsStatic)); + Assert.That(ctors.All(c => c.ReturnType.Kind == TypeKind.Void)); + Assert.That(ctors.All(c => c.Accessibility == Accessibility.Public)); } [Test] public void NoDefaultConstructorAddedToClass() { var ctors = compilation.FindType(typeof(MyClassWithCtor)).GetConstructors(); - Assert.AreEqual(Accessibility.Private, ctors.Single().Accessibility); - Assert.AreEqual(1, ctors.Single().Parameters.Count); + Assert.That(ctors.Single().Accessibility, Is.EqualTo(Accessibility.Private)); + Assert.That(ctors.Single().Parameters.Count, Is.EqualTo(1)); } [Test] public void DefaultConstructorOnAbstractClassIsProtected() { var ctors = compilation.FindType(typeof(AbstractClass)).GetConstructors(); - Assert.AreEqual(0, ctors.Single().Parameters.Count); - Assert.AreEqual(Accessibility.Protected, ctors.Single().Accessibility); + Assert.That(ctors.Single().Parameters.Count, Is.EqualTo(0)); + Assert.That(ctors.Single().Accessibility, Is.EqualTo(Accessibility.Protected)); } [Test] public void SerializableAttribute() { IAttribute attr = GetTypeDefinition(typeof(NonCustomAttributes)).GetAttributes().Single(); - Assert.AreEqual("System.SerializableAttribute", attr.AttributeType.FullName); + Assert.That(attr.AttributeType.FullName, Is.EqualTo("System.SerializableAttribute")); } [Test] public void NonSerializedAttribute() { IField field = GetTypeDefinition(typeof(NonCustomAttributes)).Fields.Single(f => f.Name == "NonSerializedField"); - Assert.AreEqual("System.NonSerializedAttribute", field.GetAttributes().Single().AttributeType.FullName); + Assert.That(field.GetAttributes().Single().AttributeType.FullName, Is.EqualTo("System.NonSerializedAttribute")); } [Test] public void ExplicitStructLayoutAttribute() { IAttribute attr = GetTypeDefinition(typeof(ExplicitFieldLayoutStruct)).GetAttributes().Single(); - Assert.AreEqual("System.Runtime.InteropServices.StructLayoutAttribute", attr.AttributeType.FullName); + Assert.That(attr.AttributeType.FullName, Is.EqualTo("System.Runtime.InteropServices.StructLayoutAttribute")); var arg1 = attr.FixedArguments.Single(); - Assert.AreEqual("System.Runtime.InteropServices.LayoutKind", arg1.Type.FullName); - Assert.AreEqual((int)LayoutKind.Explicit, arg1.Value); + Assert.That(arg1.Type.FullName, Is.EqualTo("System.Runtime.InteropServices.LayoutKind")); + Assert.That(arg1.Value, Is.EqualTo((int)LayoutKind.Explicit)); var arg2 = attr.NamedArguments[0]; - Assert.AreEqual("CharSet", arg2.Name); - Assert.AreEqual("System.Runtime.InteropServices.CharSet", arg2.Type.FullName); - Assert.AreEqual((int)CharSet.Unicode, arg2.Value); + Assert.That(arg2.Name, Is.EqualTo("CharSet")); + Assert.That(arg2.Type.FullName, Is.EqualTo("System.Runtime.InteropServices.CharSet")); + Assert.That(arg2.Value, Is.EqualTo((int)CharSet.Unicode)); var arg3 = attr.NamedArguments[1]; - Assert.AreEqual("Pack", arg3.Name); - Assert.AreEqual("System.Int32", arg3.Type.FullName); - Assert.AreEqual(8, arg3.Value); + Assert.That(arg3.Name, Is.EqualTo("Pack")); + Assert.That(arg3.Type.FullName, Is.EqualTo("System.Int32")); + Assert.That(arg3.Value, Is.EqualTo(8)); } [Test] public void FieldOffsetAttribute() { IField field = GetTypeDefinition(typeof(ExplicitFieldLayoutStruct)).Fields.Single(f => f.Name == "Field0"); - Assert.AreEqual("System.Runtime.InteropServices.FieldOffsetAttribute", field.GetAttributes().Single().AttributeType.FullName); + Assert.That(field.GetAttributes().Single().AttributeType.FullName, Is.EqualTo("System.Runtime.InteropServices.FieldOffsetAttribute")); var arg = field.GetAttributes().Single().FixedArguments.Single(); - Assert.AreEqual("System.Int32", arg.Type.FullName); - Assert.AreEqual(0, arg.Value); + Assert.That(arg.Type.FullName, Is.EqualTo("System.Int32")); + Assert.That(arg.Value, Is.EqualTo(0)); field = GetTypeDefinition(typeof(ExplicitFieldLayoutStruct)).Fields.Single(f => f.Name == "Field100"); - Assert.AreEqual("System.Runtime.InteropServices.FieldOffsetAttribute", field.GetAttributes().Single().AttributeType.FullName); + Assert.That(field.GetAttributes().Single().AttributeType.FullName, Is.EqualTo("System.Runtime.InteropServices.FieldOffsetAttribute")); arg = field.GetAttributes().Single().FixedArguments.Single(); - Assert.AreEqual("System.Int32", arg.Type.FullName); - Assert.AreEqual(100, arg.Value); + Assert.That(arg.Type.FullName, Is.EqualTo("System.Int32")); + Assert.That(arg.Value, Is.EqualTo(100)); } [Test] @@ -697,9 +694,9 @@ public void DllImportAttribute() { IMethod method = GetTypeDefinition(typeof(NonCustomAttributes)).Methods.Single(m => m.Name == "DllMethod"); IAttribute dllImport = method.GetAttributes().Single(); - Assert.AreEqual("System.Runtime.InteropServices.DllImportAttribute", dllImport.AttributeType.FullName); - Assert.AreEqual("unmanaged.dll", dllImport.FixedArguments[0].Value); - Assert.AreEqual((int)CharSet.Unicode, dllImport.NamedArguments.Single().Value); + Assert.That(dllImport.AttributeType.FullName, Is.EqualTo("System.Runtime.InteropServices.DllImportAttribute")); + Assert.That(dllImport.FixedArguments[0].Value, Is.EqualTo("unmanaged.dll")); + Assert.That(dllImport.NamedArguments.Single().Value, Is.EqualTo((int)CharSet.Unicode)); } [Test] @@ -707,9 +704,9 @@ public void DllImportAttributeWithPreserveSigFalse() { IMethod method = GetTypeDefinition(typeof(NonCustomAttributes)).Methods.Single(m => m.Name == "DoNotPreserveSig"); IAttribute dllImport = method.GetAttributes().Single(); - Assert.AreEqual("System.Runtime.InteropServices.DllImportAttribute", dllImport.AttributeType.FullName); - Assert.AreEqual("unmanaged.dll", dllImport.FixedArguments[0].Value); - Assert.AreEqual(false, dllImport.NamedArguments.Single().Value); + Assert.That(dllImport.AttributeType.FullName, Is.EqualTo("System.Runtime.InteropServices.DllImportAttribute")); + Assert.That(dllImport.FixedArguments[0].Value, Is.EqualTo("unmanaged.dll")); + Assert.That(dllImport.NamedArguments.Single().Value, Is.EqualTo(false)); } [Test] @@ -717,20 +714,20 @@ public void PreserveSigAttribute() { IMethod method = GetTypeDefinition(typeof(NonCustomAttributes)).Methods.Single(m => m.Name == "PreserveSigAsAttribute"); IAttribute preserveSig = method.GetAttributes().Single(); - Assert.AreEqual("System.Runtime.InteropServices.PreserveSigAttribute", preserveSig.AttributeType.FullName); - Assert.IsTrue(preserveSig.FixedArguments.Length == 0); - Assert.IsTrue(preserveSig.NamedArguments.Length == 0); + Assert.That(preserveSig.AttributeType.FullName, Is.EqualTo("System.Runtime.InteropServices.PreserveSigAttribute")); + Assert.That(preserveSig.FixedArguments.Length == 0); + Assert.That(preserveSig.NamedArguments.Length == 0); } [Test] public void InOutParametersOnRefMethod() { IParameter p = GetTypeDefinition(typeof(NonCustomAttributes)).Methods.Single(m => m.Name == "DllMethod").Parameters.Single(); - Assert.AreEqual(ReferenceKind.Ref, p.ReferenceKind); + Assert.That(p.ReferenceKind, Is.EqualTo(ReferenceKind.Ref)); var attr = p.GetAttributes().ToList(); - Assert.AreEqual(2, attr.Count); - Assert.AreEqual("System.Runtime.InteropServices.InAttribute", attr[0].AttributeType.FullName); - Assert.AreEqual("System.Runtime.InteropServices.OutAttribute", attr[1].AttributeType.FullName); + Assert.That(attr.Count, Is.EqualTo(2)); + Assert.That(attr[0].AttributeType.FullName, Is.EqualTo("System.Runtime.InteropServices.InAttribute")); + Assert.That(attr[1].AttributeType.FullName, Is.EqualTo("System.Runtime.InteropServices.OutAttribute")); } [Test] @@ -738,70 +735,70 @@ public void MarshalAsAttributeOnMethod() { IMethod method = GetTypeDefinition(typeof(NonCustomAttributes)).Methods.Single(m => m.Name == "DllMethod"); IAttribute marshalAs = method.GetReturnTypeAttributes().Single(); - Assert.AreEqual((int)UnmanagedType.Bool, marshalAs.FixedArguments.Single().Value); + Assert.That(marshalAs.FixedArguments.Single().Value, Is.EqualTo((int)UnmanagedType.Bool)); } [Test] public void MethodWithOutParameter() { IParameter p = GetTypeDefinition(typeof(ParameterTests)).Methods.Single(m => m.Name == "MethodWithOutParameter").Parameters.Single(); - Assert.IsFalse(p.IsOptional); - Assert.AreEqual(ReferenceKind.Out, p.ReferenceKind); - Assert.AreEqual(0, p.GetAttributes().Count()); - Assert.IsTrue(p.Type.Kind == TypeKind.ByReference); + Assert.That(!p.IsOptional); + Assert.That(p.ReferenceKind, Is.EqualTo(ReferenceKind.Out)); + Assert.That(p.GetAttributes().Count(), Is.EqualTo(0)); + Assert.That(p.Type.Kind == TypeKind.ByReference); } [Test] public void MethodWithRefParameter() { IParameter p = GetTypeDefinition(typeof(ParameterTests)).Methods.Single(m => m.Name == "MethodWithRefParameter").Parameters.Single(); - Assert.IsFalse(p.IsOptional); - Assert.AreEqual(ReferenceKind.Ref, p.ReferenceKind); - Assert.AreEqual(0, p.GetAttributes().Count()); - Assert.IsTrue(p.Type.Kind == TypeKind.ByReference); + Assert.That(!p.IsOptional); + Assert.That(p.ReferenceKind, Is.EqualTo(ReferenceKind.Ref)); + Assert.That(p.GetAttributes().Count(), Is.EqualTo(0)); + Assert.That(p.Type.Kind == TypeKind.ByReference); } [Test] public void MethodWithInParameter() { IParameter p = GetTypeDefinition(typeof(ParameterTests)).Methods.Single(m => m.Name == "MethodWithInParameter").Parameters.Single(); - Assert.IsFalse(p.IsOptional); - Assert.AreEqual(ReferenceKind.In, p.ReferenceKind); - Assert.AreEqual(0, p.GetAttributes().Count()); - Assert.IsTrue(p.Type.Kind == TypeKind.ByReference); + Assert.That(!p.IsOptional); + Assert.That(p.ReferenceKind, Is.EqualTo(ReferenceKind.In)); + Assert.That(p.GetAttributes().Count(), Is.EqualTo(0)); + Assert.That(p.Type.Kind == TypeKind.ByReference); } [Test] public void MethodWithParamsArray() { IParameter p = GetTypeDefinition(typeof(ParameterTests)).Methods.Single(m => m.Name == "MethodWithParamsArray").Parameters.Single(); - Assert.IsFalse(p.IsOptional); - Assert.AreEqual(ReferenceKind.None, p.ReferenceKind); - Assert.IsTrue(p.IsParams); - Assert.AreEqual(0, p.GetAttributes().Count()); - Assert.IsTrue(p.Type.Kind == TypeKind.Array); + Assert.That(!p.IsOptional); + Assert.That(p.ReferenceKind, Is.EqualTo(ReferenceKind.None)); + Assert.That(p.IsParams); + Assert.That(p.GetAttributes().Count(), Is.EqualTo(0)); + Assert.That(p.Type.Kind == TypeKind.Array); } [Test] public void MethodWithOptionalParameter() { IParameter p = GetTypeDefinition(typeof(ParameterTests)).Methods.Single(m => m.Name == "MethodWithOptionalParameter").Parameters.Single(); - Assert.IsTrue(p.IsOptional); - Assert.AreEqual(ReferenceKind.None, p.ReferenceKind); - Assert.IsFalse(p.IsParams); - Assert.IsTrue(p.HasConstantValueInSignature); - Assert.AreEqual(0, p.GetAttributes().Count()); - Assert.AreEqual(4, p.GetConstantValue()); + Assert.That(p.IsOptional); + Assert.That(p.ReferenceKind, Is.EqualTo(ReferenceKind.None)); + Assert.That(!p.IsParams); + Assert.That(p.HasConstantValueInSignature); + Assert.That(p.GetAttributes().Count(), Is.EqualTo(0)); + Assert.That(p.GetConstantValue(), Is.EqualTo(4)); } [Test] public void MethodWithExplicitOptionalParameter() { IParameter p = GetTypeDefinition(typeof(ParameterTests)).Methods.Single(m => m.Name == "MethodWithExplicitOptionalParameter").Parameters.Single(); - Assert.IsTrue(p.IsOptional); - Assert.AreEqual(ReferenceKind.None, p.ReferenceKind); - Assert.IsFalse(p.IsParams); - Assert.IsFalse(p.HasConstantValueInSignature); + Assert.That(p.IsOptional); + Assert.That(p.ReferenceKind, Is.EqualTo(ReferenceKind.None)); + Assert.That(!p.IsParams); + Assert.That(!p.HasConstantValueInSignature); // explicit optional parameter appears in type system if it's read from C#, but not when read from IL //Assert.AreEqual(1, p.GetAttributes().Count()); } @@ -810,103 +807,103 @@ public void MethodWithExplicitOptionalParameter() public void MethodWithEnumOptionalParameter() { IParameter p = GetTypeDefinition(typeof(ParameterTests)).Methods.Single(m => m.Name == "MethodWithEnumOptionalParameter").Parameters.Single(); - Assert.IsTrue(p.IsOptional); - Assert.AreEqual(ReferenceKind.None, p.ReferenceKind); - Assert.IsFalse(p.IsParams); - Assert.IsTrue(p.HasConstantValueInSignature); - Assert.AreEqual(0, p.GetAttributes().Count()); - Assert.AreEqual((int)StringComparison.OrdinalIgnoreCase, p.GetConstantValue()); + Assert.That(p.IsOptional); + Assert.That(p.ReferenceKind, Is.EqualTo(ReferenceKind.None)); + Assert.That(!p.IsParams); + Assert.That(p.HasConstantValueInSignature); + Assert.That(p.GetAttributes().Count(), Is.EqualTo(0)); + Assert.That(p.GetConstantValue(), Is.EqualTo((int)StringComparison.OrdinalIgnoreCase)); } [Test] public void MethodWithOptionalNullableParameter() { IParameter p = GetTypeDefinition(typeof(ParameterTests)).Methods.Single(m => m.Name == "MethodWithOptionalNullableParameter").Parameters.Single(); - Assert.IsTrue(p.IsOptional); - Assert.AreEqual(ReferenceKind.None, p.ReferenceKind); - Assert.IsFalse(p.IsParams); - Assert.IsTrue(p.HasConstantValueInSignature); - Assert.AreEqual(0, p.GetAttributes().Count()); - Assert.IsNull(p.GetConstantValue()); + Assert.That(p.IsOptional); + Assert.That(p.ReferenceKind, Is.EqualTo(ReferenceKind.None)); + Assert.That(!p.IsParams); + Assert.That(p.HasConstantValueInSignature); + Assert.That(p.GetAttributes().Count(), Is.EqualTo(0)); + Assert.That(p.GetConstantValue(), Is.Null); } [Test] public void MethodWithOptionalLongParameter() { IParameter p = GetTypeDefinition(typeof(ParameterTests)).Methods.Single(m => m.Name == "MethodWithOptionalLongParameter").Parameters.Single(); - Assert.IsTrue(p.IsOptional); - Assert.AreEqual(ReferenceKind.None, p.ReferenceKind); - Assert.IsFalse(p.IsParams); - Assert.IsTrue(p.HasConstantValueInSignature); - Assert.AreEqual(1L, p.GetConstantValue()); - Assert.AreEqual(typeof(long), p.GetConstantValue().GetType()); + Assert.That(p.IsOptional); + Assert.That(p.ReferenceKind, Is.EqualTo(ReferenceKind.None)); + Assert.That(!p.IsParams); + Assert.That(p.HasConstantValueInSignature); + Assert.That(p.GetConstantValue(), Is.EqualTo(1L)); + Assert.That(p.GetConstantValue().GetType(), Is.EqualTo(typeof(long))); } [Test] public void MethodWithOptionalNullableLongParameter() { IParameter p = GetTypeDefinition(typeof(ParameterTests)).Methods.Single(m => m.Name == "MethodWithOptionalNullableLongParameter").Parameters.Single(); - Assert.IsTrue(p.IsOptional); - Assert.AreEqual(ReferenceKind.None, p.ReferenceKind); - Assert.IsFalse(p.IsParams); - Assert.IsTrue(p.HasConstantValueInSignature); - Assert.AreEqual(1L, p.GetConstantValue()); - Assert.AreEqual(typeof(long), p.GetConstantValue().GetType()); + Assert.That(p.IsOptional); + Assert.That(p.ReferenceKind, Is.EqualTo(ReferenceKind.None)); + Assert.That(!p.IsParams); + Assert.That(p.HasConstantValueInSignature); + Assert.That(p.GetConstantValue(), Is.EqualTo(1L)); + Assert.That(p.GetConstantValue().GetType(), Is.EqualTo(typeof(long))); } [Test] public void MethodWithOptionalDecimalParameter() { IParameter p = GetTypeDefinition(typeof(ParameterTests)).Methods.Single(m => m.Name == "MethodWithOptionalDecimalParameter").Parameters.Single(); - Assert.IsTrue(p.IsOptional); - Assert.AreEqual(ReferenceKind.None, p.ReferenceKind); - Assert.IsFalse(p.IsParams); - Assert.IsTrue(p.HasConstantValueInSignature); - Assert.AreEqual(1M, p.GetConstantValue()); - Assert.AreEqual(typeof(decimal), p.GetConstantValue().GetType()); + Assert.That(p.IsOptional); + Assert.That(p.ReferenceKind, Is.EqualTo(ReferenceKind.None)); + Assert.That(!p.IsParams); + Assert.That(p.HasConstantValueInSignature); + Assert.That(p.GetConstantValue(), Is.EqualTo(1M)); + Assert.That(p.GetConstantValue().GetType(), Is.EqualTo(typeof(decimal))); } [Test] public void VarArgsMethod() { IParameter p = GetTypeDefinition(typeof(ParameterTests)).Methods.Single(m => m.Name == "VarArgsMethod").Parameters.Single(); - Assert.IsFalse(p.IsOptional); - Assert.AreEqual(ReferenceKind.None, p.ReferenceKind); - Assert.IsFalse(p.IsParams); - Assert.AreEqual(TypeKind.ArgList, p.Type.Kind); - Assert.AreEqual("", p.Name); + Assert.That(!p.IsOptional); + Assert.That(p.ReferenceKind, Is.EqualTo(ReferenceKind.None)); + Assert.That(!p.IsParams); + Assert.That(p.Type.Kind, Is.EqualTo(TypeKind.ArgList)); + Assert.That(p.Name, Is.EqualTo("")); } [Test] public void VarArgsCtor() { IParameter p = GetTypeDefinition(typeof(VarArgsCtor)).Methods.Single(m => m.IsConstructor).Parameters.Single(); - Assert.IsFalse(p.IsOptional); - Assert.AreEqual(ReferenceKind.None, p.ReferenceKind); - Assert.IsFalse(p.IsParams); - Assert.AreEqual(TypeKind.ArgList, p.Type.Kind); - Assert.AreEqual("", p.Name); + Assert.That(!p.IsOptional); + Assert.That(p.ReferenceKind, Is.EqualTo(ReferenceKind.None)); + Assert.That(!p.IsParams); + Assert.That(p.Type.Kind, Is.EqualTo(TypeKind.ArgList)); + Assert.That(p.Name, Is.EqualTo("")); } [Test] public void GenericDelegate_Variance() { ITypeDefinition type = GetTypeDefinition(typeof(GenericDelegate<,>)); - Assert.AreEqual(VarianceModifier.Contravariant, type.TypeParameters[0].Variance); - Assert.AreEqual(VarianceModifier.Covariant, type.TypeParameters[1].Variance); + Assert.That(type.TypeParameters[0].Variance, Is.EqualTo(VarianceModifier.Contravariant)); + Assert.That(type.TypeParameters[1].Variance, Is.EqualTo(VarianceModifier.Covariant)); - Assert.AreSame(type.TypeParameters[1], type.TypeParameters[0].DirectBaseTypes.FirstOrDefault()); + Assert.That(type.TypeParameters[0].DirectBaseTypes.FirstOrDefault(), Is.SameAs(type.TypeParameters[1])); } [Test] public void GenericDelegate_ReferenceTypeConstraints() { ITypeDefinition type = GetTypeDefinition(typeof(GenericDelegate<,>)); - Assert.IsFalse(type.TypeParameters[0].HasReferenceTypeConstraint); - Assert.IsTrue(type.TypeParameters[1].HasReferenceTypeConstraint); + Assert.That(!type.TypeParameters[0].HasReferenceTypeConstraint); + Assert.That(type.TypeParameters[1].HasReferenceTypeConstraint); - Assert.IsNull(type.TypeParameters[0].IsReferenceType); - Assert.AreEqual(true, type.TypeParameters[1].IsReferenceType); + Assert.That(type.TypeParameters[0].IsReferenceType, Is.Null); + Assert.That(type.TypeParameters[1].IsReferenceType, Is.EqualTo(true)); } [Test] @@ -914,9 +911,9 @@ public void GenericDelegate_GetInvokeMethod() { IType type = compilation.FindType(typeof(GenericDelegate)); IMethod m = type.GetDelegateInvokeMethod(); - Assert.AreEqual("Invoke", m.Name); - Assert.AreEqual("System.Object", m.ReturnType.FullName); - Assert.AreEqual("System.String", m.Parameters[0].Type.FullName); + Assert.That(m.Name, Is.EqualTo("Invoke")); + Assert.That(m.ReturnType.FullName, Is.EqualTo("System.Object")); + Assert.That(m.Parameters[0].Type.FullName, Is.EqualTo("System.String")); } [Test] @@ -924,14 +921,14 @@ public void ComInterfaceTest() { ITypeDefinition type = GetTypeDefinition(typeof(IAssemblyEnum)); // [ComImport] - Assert.AreEqual(1, type.GetAttributes().Count(a => a.AttributeType.FullName == typeof(ComImportAttribute).FullName)); + Assert.That(type.GetAttributes().Count(a => a.AttributeType.FullName == typeof(ComImportAttribute).FullName), Is.EqualTo(1)); IMethod m = type.Methods.Single(); - Assert.AreEqual("GetNextAssembly", m.Name); - Assert.AreEqual(Accessibility.Public, m.Accessibility); - Assert.IsTrue(m.IsAbstract); - Assert.IsFalse(m.IsVirtual); - Assert.IsFalse(m.IsSealed); + Assert.That(m.Name, Is.EqualTo("GetNextAssembly")); + Assert.That(m.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(m.IsAbstract); + Assert.That(!m.IsVirtual); + Assert.That(!m.IsSealed); } [Test] @@ -943,9 +940,9 @@ public void InnerClassInGenericClassIsReferencedUsingParameterizedType() IField field3 = type.Fields.Single(f => f.Name == "Field3"); // types must be self-parameterized - Assert.AreEqual("ICSharpCode.Decompiler.Tests.TypeSystem.OuterGeneric`1+Inner[[`0]]", field1.Type.ReflectionName); - Assert.AreEqual("ICSharpCode.Decompiler.Tests.TypeSystem.OuterGeneric`1+Inner[[`0]]", field2.Type.ReflectionName); - Assert.AreEqual("ICSharpCode.Decompiler.Tests.TypeSystem.OuterGeneric`1+Inner[[ICSharpCode.Decompiler.Tests.TypeSystem.OuterGeneric`1+Inner[[`0]]]]", field3.Type.ReflectionName); + Assert.That(field1.Type.ReflectionName, Is.EqualTo("ICSharpCode.Decompiler.Tests.TypeSystem.OuterGeneric`1+Inner[[`0]]")); + Assert.That(field2.Type.ReflectionName, Is.EqualTo("ICSharpCode.Decompiler.Tests.TypeSystem.OuterGeneric`1+Inner[[`0]]")); + Assert.That(field3.Type.ReflectionName, Is.EqualTo("ICSharpCode.Decompiler.Tests.TypeSystem.OuterGeneric`1+Inner[[ICSharpCode.Decompiler.Tests.TypeSystem.OuterGeneric`1+Inner[[`0]]]]")); } [Test] @@ -953,67 +950,67 @@ public void FlagsOnInterfaceMembersAreCorrect() { ITypeDefinition type = GetTypeDefinition(typeof(IInterfaceWithProperty)); var p = type.Properties.Single(); - Assert.AreEqual(false, p.IsIndexer); - Assert.AreEqual(true, p.IsAbstract); - Assert.AreEqual(true, p.IsOverridable); - Assert.AreEqual(false, p.IsOverride); - Assert.AreEqual(Accessibility.Public, p.Accessibility); - Assert.AreEqual(true, p.Getter.IsAbstract); - Assert.AreEqual(true, p.Getter.IsOverridable); - Assert.AreEqual(false, p.Getter.IsOverride); - Assert.AreEqual(Accessibility.Public, p.Getter.Accessibility); - Assert.AreEqual(false, p.Getter.HasBody); - Assert.AreEqual(true, p.Setter.IsAbstract); - Assert.AreEqual(true, p.Setter.IsOverridable); - Assert.AreEqual(false, p.Setter.IsOverride); - Assert.AreEqual(Accessibility.Public, p.Setter.Accessibility); - Assert.AreEqual(false, p.Setter.HasBody); + Assert.That(p.IsIndexer, Is.EqualTo(false)); + Assert.That(p.IsAbstract, Is.EqualTo(true)); + Assert.That(p.IsOverridable, Is.EqualTo(true)); + Assert.That(p.IsOverride, Is.EqualTo(false)); + Assert.That(p.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(p.Getter.IsAbstract, Is.EqualTo(true)); + Assert.That(p.Getter.IsOverridable, Is.EqualTo(true)); + Assert.That(p.Getter.IsOverride, Is.EqualTo(false)); + Assert.That(p.Getter.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(p.Getter.HasBody, Is.EqualTo(false)); + Assert.That(p.Setter.IsAbstract, Is.EqualTo(true)); + Assert.That(p.Setter.IsOverridable, Is.EqualTo(true)); + Assert.That(p.Setter.IsOverride, Is.EqualTo(false)); + Assert.That(p.Setter.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(p.Setter.HasBody, Is.EqualTo(false)); type = GetTypeDefinition(typeof(IInterfaceWithIndexers)); p = type.Properties.Single(x => x.Parameters.Count == 2); - Assert.AreEqual(true, p.IsIndexer); - Assert.AreEqual(true, p.IsAbstract); - Assert.AreEqual(true, p.IsOverridable); - Assert.AreEqual(false, p.IsOverride); - Assert.AreEqual(Accessibility.Public, p.Accessibility); - Assert.AreEqual(true, p.Getter.IsAbstract); - Assert.AreEqual(true, p.Getter.IsOverridable); - Assert.AreEqual(false, p.Getter.IsOverride); - Assert.AreEqual(Accessibility.Public, p.Getter.Accessibility); - Assert.AreEqual(true, p.Setter.IsAbstract); - Assert.AreEqual(true, p.Setter.IsOverridable); - Assert.AreEqual(false, p.Setter.IsOverride); - Assert.AreEqual(Accessibility.Public, p.Setter.Accessibility); + Assert.That(p.IsIndexer, Is.EqualTo(true)); + Assert.That(p.IsAbstract, Is.EqualTo(true)); + Assert.That(p.IsOverridable, Is.EqualTo(true)); + Assert.That(p.IsOverride, Is.EqualTo(false)); + Assert.That(p.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(p.Getter.IsAbstract, Is.EqualTo(true)); + Assert.That(p.Getter.IsOverridable, Is.EqualTo(true)); + Assert.That(p.Getter.IsOverride, Is.EqualTo(false)); + Assert.That(p.Getter.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(p.Setter.IsAbstract, Is.EqualTo(true)); + Assert.That(p.Setter.IsOverridable, Is.EqualTo(true)); + Assert.That(p.Setter.IsOverride, Is.EqualTo(false)); + Assert.That(p.Setter.Accessibility, Is.EqualTo(Accessibility.Public)); type = GetTypeDefinition(typeof(IHasEvent)); var e = type.Events.Single(); - Assert.AreEqual(true, e.IsAbstract); - Assert.AreEqual(true, e.IsOverridable); - Assert.AreEqual(false, e.IsOverride); - Assert.AreEqual(Accessibility.Public, e.Accessibility); - Assert.AreEqual(true, e.AddAccessor.IsAbstract); - Assert.AreEqual(true, e.AddAccessor.IsOverridable); - Assert.AreEqual(false, e.AddAccessor.IsOverride); - Assert.AreEqual(Accessibility.Public, e.AddAccessor.Accessibility); - Assert.AreEqual(true, e.RemoveAccessor.IsAbstract); - Assert.AreEqual(true, e.RemoveAccessor.IsOverridable); - Assert.AreEqual(false, e.RemoveAccessor.IsOverride); - Assert.AreEqual(Accessibility.Public, e.RemoveAccessor.Accessibility); + Assert.That(e.IsAbstract, Is.EqualTo(true)); + Assert.That(e.IsOverridable, Is.EqualTo(true)); + Assert.That(e.IsOverride, Is.EqualTo(false)); + Assert.That(e.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(e.AddAccessor.IsAbstract, Is.EqualTo(true)); + Assert.That(e.AddAccessor.IsOverridable, Is.EqualTo(true)); + Assert.That(e.AddAccessor.IsOverride, Is.EqualTo(false)); + Assert.That(e.AddAccessor.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(e.RemoveAccessor.IsAbstract, Is.EqualTo(true)); + Assert.That(e.RemoveAccessor.IsOverridable, Is.EqualTo(true)); + Assert.That(e.RemoveAccessor.IsOverride, Is.EqualTo(false)); + Assert.That(e.RemoveAccessor.Accessibility, Is.EqualTo(Accessibility.Public)); type = GetTypeDefinition(typeof(IDisposable)); var m = type.Methods.Single(); - Assert.AreEqual(true, m.IsAbstract); - Assert.AreEqual(true, m.IsOverridable); - Assert.AreEqual(false, m.IsOverride); - Assert.AreEqual(Accessibility.Public, m.Accessibility); + Assert.That(m.IsAbstract, Is.EqualTo(true)); + Assert.That(m.IsOverridable, Is.EqualTo(true)); + Assert.That(m.IsOverride, Is.EqualTo(false)); + Assert.That(m.Accessibility, Is.EqualTo(Accessibility.Public)); } [Test] public void InnerClassInGenericClass_TypeParameterOwner() { ITypeDefinition type = GetTypeDefinition(typeof(OuterGeneric<>.Inner)); - Assert.AreSame(type.DeclaringTypeDefinition.TypeParameters[0], type.TypeParameters[0]); - Assert.AreSame(type.DeclaringTypeDefinition, type.TypeParameters[0].Owner); + Assert.That(type.TypeParameters[0], Is.SameAs(type.DeclaringTypeDefinition.TypeParameters[0])); + Assert.That(type.TypeParameters[0].Owner, Is.SameAs(type.DeclaringTypeDefinition)); } [Test] @@ -1021,7 +1018,7 @@ public void InnerClassInGenericClass_ReferencesTheOuterClass_Field() { ITypeDefinition type = GetTypeDefinition(typeof(OuterGeneric<>.Inner)); IField f = type.Fields.Single(); - Assert.AreEqual("ICSharpCode.Decompiler.Tests.TypeSystem.OuterGeneric`1[[`0]]", f.Type.ReflectionName); + Assert.That(f.Type.ReflectionName, Is.EqualTo("ICSharpCode.Decompiler.Tests.TypeSystem.OuterGeneric`1[[`0]]")); } [Test] @@ -1029,14 +1026,14 @@ public void InnerClassInGenericClass_ReferencesTheOuterClass_Parameter() { ITypeDefinition type = GetTypeDefinition(typeof(OuterGeneric<>.Inner)); IParameter p = type.Methods.Single(m => m.IsConstructor).Parameters.Single(); - Assert.AreEqual("ICSharpCode.Decompiler.Tests.TypeSystem.OuterGeneric`1[[`0]]", p.Type.ReflectionName); + Assert.That(p.Type.ReflectionName, Is.EqualTo("ICSharpCode.Decompiler.Tests.TypeSystem.OuterGeneric`1[[`0]]")); } CustomAttributeTypedArgument GetParamsAttributeArgument(int index) { ITypeDefinition type = GetTypeDefinition(typeof(ParamsAttribute)); var arr = (AttributeArray)type.GetAttributes().Single().FixedArguments.Single().Value; - Assert.AreEqual(5, arr.Length); + Assert.That(arr.Length, Is.EqualTo(5)); return arr[index]; } @@ -1044,16 +1041,16 @@ CustomAttributeTypedArgument GetParamsAttributeArgument(int index) public void ParamsAttribute_Integer() { var arg = GetParamsAttributeArgument(0); - Assert.AreEqual("System.Int32", arg.Type.FullName); - Assert.AreEqual(1, arg.Value); + Assert.That(arg.Type.FullName, Is.EqualTo("System.Int32")); + Assert.That(arg.Value, Is.EqualTo(1)); } [Test] public void ParamsAttribute_Enum() { var arg = GetParamsAttributeArgument(1); - Assert.AreEqual("System.StringComparison", arg.Type.FullName); - Assert.AreEqual((int)StringComparison.CurrentCulture, arg.Value); + Assert.That(arg.Type.FullName, Is.EqualTo("System.StringComparison")); + Assert.That(arg.Value, Is.EqualTo((int)StringComparison.CurrentCulture)); } [Test] @@ -1061,23 +1058,23 @@ public void ParamsAttribute_NullReference() { var arg = GetParamsAttributeArgument(2); //Assert.AreEqual("System.Object", arg.Type.FullName); - Assert.IsNull(arg.Value); + Assert.That(arg.Value, Is.Null); } [Test] public void ParamsAttribute_Double() { var arg = GetParamsAttributeArgument(3); - Assert.AreEqual("System.Double", arg.Type.FullName); - Assert.AreEqual(4.0, arg.Value); + Assert.That(arg.Type.FullName, Is.EqualTo("System.Double")); + Assert.That(arg.Value, Is.EqualTo(4.0)); } [Test] public void ParamsAttribute_String() { var arg = GetParamsAttributeArgument(4); - Assert.AreEqual("System.String", arg.Type.FullName); - Assert.AreEqual("Test", arg.Value); + Assert.That(arg.Type.FullName, Is.EqualTo("System.String")); + Assert.That(arg.Value, Is.EqualTo("Test")); } [Test] @@ -1086,15 +1083,15 @@ public void ParamsAttribute_Property() ITypeDefinition type = GetTypeDefinition(typeof(ParamsAttribute)); IProperty prop = type.Properties.Single(p => p.Name == "Property"); var attr = prop.GetAttributes().Single(); - Assert.AreEqual(type, attr.AttributeType); + Assert.That(attr.AttributeType, Is.EqualTo(type)); var elements = (AttributeArray)attr.FixedArguments.Single().Value; - Assert.AreEqual(0, elements.Length); + Assert.That(elements.Length, Is.EqualTo(0)); var namedArg = attr.NamedArguments.Single(); - Assert.AreEqual(prop.Name, namedArg.Name); + Assert.That(namedArg.Name, Is.EqualTo(prop.Name)); var arrayElements = (AttributeArray)namedArg.Value; - Assert.AreEqual(2, arrayElements.Length); + Assert.That(arrayElements.Length, Is.EqualTo(2)); } [Test] @@ -1102,8 +1099,8 @@ public void ParamsAttribute_Getter_ReturnType() { ITypeDefinition type = GetTypeDefinition(typeof(ParamsAttribute)); IProperty prop = type.Properties.Single(p => p.Name == "Property"); - Assert.AreEqual(0, prop.Getter.GetAttributes().Count()); - Assert.AreEqual(1, prop.Getter.GetReturnTypeAttributes().Count()); + Assert.That(prop.Getter.GetAttributes().Count(), Is.EqualTo(0)); + Assert.That(prop.Getter.GetReturnTypeAttributes().Count(), Is.EqualTo(1)); } [Test] @@ -1111,8 +1108,8 @@ public void DoubleAttribute_ImplicitNumericConversion() { ITypeDefinition type = GetTypeDefinition(typeof(DoubleAttribute)); var arg = type.GetAttributes().Single().FixedArguments.Single(); - Assert.AreEqual("System.Double", arg.Type.ReflectionName); - Assert.AreEqual(1.0, arg.Value); + Assert.That(arg.Type.ReflectionName, Is.EqualTo("System.Double")); + Assert.That(arg.Value, Is.EqualTo(1.0)); } /* TS no longer provides implicitly implemented interface members. @@ -1135,24 +1132,24 @@ public void StaticityOfEventAccessors() // https://github.com/icsharpcode/NRefactory/issues/20 ITypeDefinition type = GetTypeDefinition(typeof(ClassWithStaticAndNonStaticMembers)); var evt1 = type.Events.Single(e => e.Name == "Event1"); - Assert.IsTrue(evt1.IsStatic); - Assert.IsTrue(evt1.AddAccessor.IsStatic); - Assert.IsTrue(evt1.RemoveAccessor.IsStatic); + Assert.That(evt1.IsStatic); + Assert.That(evt1.AddAccessor.IsStatic); + Assert.That(evt1.RemoveAccessor.IsStatic); var evt2 = type.Events.Single(e => e.Name == "Event2"); - Assert.IsFalse(evt2.IsStatic); - Assert.IsFalse(evt2.AddAccessor.IsStatic); - Assert.IsFalse(evt2.RemoveAccessor.IsStatic); + Assert.That(!evt2.IsStatic); + Assert.That(!evt2.AddAccessor.IsStatic); + Assert.That(!evt2.RemoveAccessor.IsStatic); var evt3 = type.Events.Single(e => e.Name == "Event3"); - Assert.IsTrue(evt3.IsStatic); - Assert.IsTrue(evt3.AddAccessor.IsStatic); - Assert.IsTrue(evt3.RemoveAccessor.IsStatic); + Assert.That(evt3.IsStatic); + Assert.That(evt3.AddAccessor.IsStatic); + Assert.That(evt3.RemoveAccessor.IsStatic); var evt4 = type.Events.Single(e => e.Name == "Event4"); - Assert.IsFalse(evt4.IsStatic); - Assert.IsFalse(evt4.AddAccessor.IsStatic); - Assert.IsFalse(evt4.RemoveAccessor.IsStatic); + Assert.That(!evt4.IsStatic); + Assert.That(!evt4.AddAccessor.IsStatic); + Assert.That(!evt4.RemoveAccessor.IsStatic); } [Test] @@ -1161,24 +1158,24 @@ public void StaticityOfPropertyAccessors() // https://github.com/icsharpcode/NRefactory/issues/20 ITypeDefinition type = GetTypeDefinition(typeof(ClassWithStaticAndNonStaticMembers)); var prop1 = type.Properties.Single(e => e.Name == "Prop1"); - Assert.IsTrue(prop1.IsStatic); - Assert.IsTrue(prop1.Getter.IsStatic); - Assert.IsTrue(prop1.Setter.IsStatic); + Assert.That(prop1.IsStatic); + Assert.That(prop1.Getter.IsStatic); + Assert.That(prop1.Setter.IsStatic); var prop2 = type.Properties.Single(e => e.Name == "Prop2"); - Assert.IsFalse(prop2.IsStatic); - Assert.IsFalse(prop2.Getter.IsStatic); - Assert.IsFalse(prop2.Setter.IsStatic); + Assert.That(!prop2.IsStatic); + Assert.That(!prop2.Getter.IsStatic); + Assert.That(!prop2.Setter.IsStatic); var prop3 = type.Properties.Single(e => e.Name == "Prop3"); - Assert.IsTrue(prop3.IsStatic); - Assert.IsTrue(prop3.Getter.IsStatic); - Assert.IsTrue(prop3.Setter.IsStatic); + Assert.That(prop3.IsStatic); + Assert.That(prop3.Getter.IsStatic); + Assert.That(prop3.Setter.IsStatic); var prop4 = type.Properties.Single(e => e.Name == "Prop4"); - Assert.IsFalse(prop4.IsStatic); - Assert.IsFalse(prop4.Getter.IsStatic); - Assert.IsFalse(prop4.Setter.IsStatic); + Assert.That(!prop4.IsStatic); + Assert.That(!prop4.Getter.IsStatic); + Assert.That(!prop4.Setter.IsStatic); } [Test] @@ -1187,8 +1184,8 @@ public void PropertyAccessorsHaveBody() ITypeDefinition type = GetTypeDefinition(typeof(ClassWithStaticAndNonStaticMembers)); foreach (var prop in type.Properties) { - Assert.IsTrue(prop.Getter.HasBody, prop.Getter.Name); - Assert.IsTrue(prop.Setter.HasBody, prop.Setter.Name); + Assert.That(prop.Getter.HasBody, prop.Getter.Name); + Assert.That(prop.Setter.HasBody, prop.Setter.Name); } } @@ -1197,12 +1194,12 @@ public void EventAccessorNames() { ITypeDefinition type = GetTypeDefinition(typeof(ClassWithStaticAndNonStaticMembers)); var customEvent = type.Events.Single(e => e.Name == "Event1"); - Assert.AreEqual("add_Event1", customEvent.AddAccessor.Name); - Assert.AreEqual("remove_Event1", customEvent.RemoveAccessor.Name); + Assert.That(customEvent.AddAccessor.Name, Is.EqualTo("add_Event1")); + Assert.That(customEvent.RemoveAccessor.Name, Is.EqualTo("remove_Event1")); var normalEvent = type.Events.Single(e => e.Name == "Event3"); - Assert.AreEqual("add_Event3", normalEvent.AddAccessor.Name); - Assert.AreEqual("remove_Event3", normalEvent.RemoveAccessor.Name); + Assert.That(normalEvent.AddAccessor.Name, Is.EqualTo("add_Event3")); + Assert.That(normalEvent.RemoveAccessor.Name, Is.EqualTo("remove_Event3")); } [Test] @@ -1211,8 +1208,8 @@ public void EventAccessorHaveBody() ITypeDefinition type = GetTypeDefinition(typeof(ClassWithStaticAndNonStaticMembers)); foreach (var ev in type.Events) { - Assert.IsTrue(ev.AddAccessor.HasBody, ev.AddAccessor.Name); - Assert.IsTrue(ev.RemoveAccessor.HasBody, ev.RemoveAccessor.Name); + Assert.That(ev.AddAccessor.HasBody, ev.AddAccessor.Name); + Assert.That(ev.RemoveAccessor.HasBody, ev.RemoveAccessor.Name); } } @@ -1270,8 +1267,8 @@ public void ClassThatOverridesGetterOnly() { ITypeDefinition type = GetTypeDefinition(typeof(ClassThatOverridesGetterOnly)); var prop = type.Properties.Single(p => p.Name == "Prop"); - Assert.AreEqual(Accessibility.Public, prop.Accessibility); - Assert.AreEqual(Accessibility.Public, prop.Getter.Accessibility); + Assert.That(prop.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(prop.Getter.Accessibility, Is.EqualTo(Accessibility.Public)); } [Test] @@ -1279,8 +1276,8 @@ public void ClassThatOverridesSetterOnly() { ITypeDefinition type = GetTypeDefinition(typeof(ClassThatOverridesSetterOnly)); var prop = type.Properties.Single(p => p.Name == "Prop"); - Assert.AreEqual(Accessibility.Public, prop.Accessibility); - Assert.AreEqual(Accessibility.Protected, prop.Setter.Accessibility); + Assert.That(prop.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(prop.Setter.Accessibility, Is.EqualTo(Accessibility.Protected)); } /* TS no longer provides implicit interface impls @@ -1300,9 +1297,9 @@ public void PropertyThatImplementsInterfaceIsNotVirtual() { ITypeDefinition type = GetTypeDefinition(typeof(ClassThatImplementsProperty)); var prop = type.Properties.Single(p => p.Name == "Prop"); - Assert.IsFalse(prop.IsVirtual); - Assert.IsFalse(prop.IsOverridable); - Assert.IsFalse(prop.IsSealed); + Assert.That(!prop.IsVirtual); + Assert.That(!prop.IsOverridable); + Assert.That(!prop.IsSealed); } [Test] @@ -1310,10 +1307,10 @@ public void Property_SealedOverride() { ITypeDefinition type = GetTypeDefinition(typeof(ClassThatOverridesAndSealsVirtualProperty)); var prop = type.Properties.Single(p => p.Name == "Prop"); - Assert.IsFalse(prop.IsVirtual); - Assert.IsTrue(prop.IsOverride); - Assert.IsTrue(prop.IsSealed); - Assert.IsFalse(prop.IsOverridable); + Assert.That(!prop.IsVirtual); + Assert.That(prop.IsOverride); + Assert.That(prop.IsSealed); + Assert.That(!prop.IsOverridable); } /* The TS no longer provides implicit interface impls. @@ -1365,26 +1362,26 @@ public void ExplicitDisposableImplementation() { ITypeDefinition disposable = GetTypeDefinition(typeof(ExplicitDisposableImplementation)); IMethod method = disposable.Methods.Single(m => !m.IsConstructor); - Assert.IsTrue(method.IsExplicitInterfaceImplementation); - Assert.AreEqual("System.IDisposable.Dispose", method.ExplicitlyImplementedInterfaceMembers.Single().FullName); + Assert.That(method.IsExplicitInterfaceImplementation); + Assert.That(method.ExplicitlyImplementedInterfaceMembers.Single().FullName, Is.EqualTo("System.IDisposable.Dispose")); } [Test] public void ExplicitImplementationOfUnifiedMethods() { IType type = compilation.FindType(typeof(ExplicitGenericInterfaceImplementationWithUnifiableMethods)); - Assert.AreEqual(2, type.GetMethods(m => m.IsExplicitInterfaceImplementation).Count()); + Assert.That(type.GetMethods(m => m.IsExplicitInterfaceImplementation).Count(), Is.EqualTo(2)); foreach (IMethod method in type.GetMethods(m => m.IsExplicitInterfaceImplementation)) { - Assert.AreEqual(1, method.ExplicitlyImplementedInterfaceMembers.Count(), method.ToString()); - Assert.AreEqual("System.Int32", method.Parameters.Single().Type.ReflectionName); + Assert.That(method.ExplicitlyImplementedInterfaceMembers.Count(), Is.EqualTo(1), method.ToString()); + Assert.That(method.Parameters.Single().Type.ReflectionName, Is.EqualTo("System.Int32")); IMethod interfaceMethod = (IMethod)method.ExplicitlyImplementedInterfaceMembers.Single(); - Assert.AreEqual("System.Int32", interfaceMethod.Parameters.Single().Type.ReflectionName); + Assert.That(interfaceMethod.Parameters.Single().Type.ReflectionName, Is.EqualTo("System.Int32")); var genericParamType = ((IMethod)method.MemberDefinition).Parameters.Single().Type; var interfaceGenericParamType = ((IMethod)interfaceMethod.MemberDefinition).Parameters.Single().Type; - Assert.AreEqual(TypeKind.TypeParameter, genericParamType.Kind); - Assert.AreEqual(TypeKind.TypeParameter, interfaceGenericParamType.Kind); - Assert.AreEqual(genericParamType.ReflectionName, interfaceGenericParamType.ReflectionName); + Assert.That(genericParamType.Kind, Is.EqualTo(TypeKind.TypeParameter)); + Assert.That(interfaceGenericParamType.Kind, Is.EqualTo(TypeKind.TypeParameter)); + Assert.That(interfaceGenericParamType.ReflectionName, Is.EqualTo(genericParamType.ReflectionName)); } } @@ -1395,16 +1392,16 @@ public void ExplicitGenericInterfaceImplementation() IType genericInterfaceOfString = compilation.FindType(typeof(IGenericInterface)); IMethod implMethod1 = impl.Methods.Single(m => !m.IsConstructor && !m.Parameters[1].IsRef); IMethod implMethod2 = impl.Methods.Single(m => !m.IsConstructor && m.Parameters[1].IsRef); - Assert.IsTrue(implMethod1.IsExplicitInterfaceImplementation); - Assert.IsTrue(implMethod2.IsExplicitInterfaceImplementation); + Assert.That(implMethod1.IsExplicitInterfaceImplementation); + Assert.That(implMethod2.IsExplicitInterfaceImplementation); IMethod interfaceMethod1 = (IMethod)implMethod1.ExplicitlyImplementedInterfaceMembers.Single(); - Assert.AreEqual(genericInterfaceOfString, interfaceMethod1.DeclaringType); - Assert.IsTrue(!interfaceMethod1.Parameters[1].IsRef); + Assert.That(interfaceMethod1.DeclaringType, Is.EqualTo(genericInterfaceOfString)); + Assert.That(!interfaceMethod1.Parameters[1].IsRef); IMethod interfaceMethod2 = (IMethod)implMethod2.ExplicitlyImplementedInterfaceMembers.Single(); - Assert.AreEqual(genericInterfaceOfString, interfaceMethod2.DeclaringType); - Assert.IsTrue(interfaceMethod2.Parameters[1].IsRef); + Assert.That(interfaceMethod2.DeclaringType, Is.EqualTo(genericInterfaceOfString)); + Assert.That(interfaceMethod2.Parameters[1].IsRef); } [Test] @@ -1422,9 +1419,9 @@ public void ExplicitlyImplementedPropertiesShouldHaveExplicitlyImplementedAccess { ITypeDefinition type = GetTypeDefinition(typeof(ClassThatImplementsPropertyExplicitly)); var prop = type.Properties.Single(); - Assert.IsTrue(prop.IsExplicitInterfaceImplementation); - Assert.IsTrue(prop.Getter.IsExplicitInterfaceImplementation); - Assert.IsTrue(prop.Setter.IsExplicitInterfaceImplementation); + Assert.That(prop.IsExplicitInterfaceImplementation); + Assert.That(prop.Getter.IsExplicitInterfaceImplementation); + Assert.That(prop.Setter.IsExplicitInterfaceImplementation); } /* The TS no longer provides implicit interface impls. @@ -1484,9 +1481,9 @@ public void MembersDeclaredInDerivedInterfacesDoNotImplementBaseMembers() public void StaticClassTest() { ITypeDefinition type = GetTypeDefinition(typeof(StaticClass)); - Assert.IsTrue(type.IsAbstract); - Assert.IsTrue(type.IsSealed); - Assert.IsTrue(type.IsStatic); + Assert.That(type.IsAbstract); + Assert.That(type.IsSealed); + Assert.That(type.IsStatic); } [Test] @@ -1495,18 +1492,18 @@ public void ExtensionMethodTest() ITypeDefinition type = GetTypeDefinition(typeof(StaticClass)); var method = type.Methods.Single(m => m.Name == "Extension"); - Assert.IsTrue(method.IsStatic); - Assert.IsTrue(method.IsExtensionMethod); - Assert.IsNull(method.ReducedFrom); + Assert.That(method.IsStatic); + Assert.That(method.IsExtensionMethod); + Assert.That(method.ReducedFrom, Is.Null); - Assert.IsTrue(type.HasExtensionMethods); + Assert.That(type.HasExtensionMethods); } [Test] public void NoDefaultConstructorOnStaticClassTest() { ITypeDefinition type = GetTypeDefinition(typeof(StaticClass)); - Assert.AreEqual(0, type.GetConstructors().Count()); + Assert.That(type.GetConstructors().Count(), Is.EqualTo(0)); } [Test] @@ -1514,7 +1511,7 @@ public void IndexerNonDefaultName() { ITypeDefinition type = GetTypeDefinition(typeof(IndexerNonDefaultName)); var indexer = type.GetProperties(p => p.IsIndexer).Single(); - Assert.AreEqual("Foo", indexer.Name); + Assert.That(indexer.Name, Is.EqualTo("Foo")); } [Test] @@ -1522,28 +1519,28 @@ public void TestNullableDefaultParameter() { ITypeDefinition type = GetTypeDefinition(typeof(ClassWithMethodThatHasNullableDefaultParameter)); var method = type.GetMethods().Single(m => m.Name == "Foo"); - Assert.AreEqual(42, method.Parameters.Single().GetConstantValue()); + Assert.That(method.Parameters.Single().GetConstantValue(), Is.EqualTo(42)); } [Test] public void AccessibilityTests() { ITypeDefinition type = GetTypeDefinition(typeof(AccessibilityTest)); - Assert.AreEqual(Accessibility.Public, type.Methods.Single(m => m.Name == "Public").Accessibility); - Assert.AreEqual(Accessibility.Internal, type.Methods.Single(m => m.Name == "Internal").Accessibility); - Assert.AreEqual(Accessibility.ProtectedOrInternal, type.Methods.Single(m => m.Name == "ProtectedInternal").Accessibility); - Assert.AreEqual(Accessibility.ProtectedOrInternal, type.Methods.Single(m => m.Name == "InternalProtected").Accessibility); - Assert.AreEqual(Accessibility.Protected, type.Methods.Single(m => m.Name == "Protected").Accessibility); - Assert.AreEqual(Accessibility.Private, type.Methods.Single(m => m.Name == "Private").Accessibility); - Assert.AreEqual(Accessibility.Private, type.Methods.Single(m => m.Name == "None").Accessibility); + Assert.That(type.Methods.Single(m => m.Name == "Public").Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(type.Methods.Single(m => m.Name == "Internal").Accessibility, Is.EqualTo(Accessibility.Internal)); + Assert.That(type.Methods.Single(m => m.Name == "ProtectedInternal").Accessibility, Is.EqualTo(Accessibility.ProtectedOrInternal)); + Assert.That(type.Methods.Single(m => m.Name == "InternalProtected").Accessibility, Is.EqualTo(Accessibility.ProtectedOrInternal)); + Assert.That(type.Methods.Single(m => m.Name == "Protected").Accessibility, Is.EqualTo(Accessibility.Protected)); + Assert.That(type.Methods.Single(m => m.Name == "Private").Accessibility, Is.EqualTo(Accessibility.Private)); + Assert.That(type.Methods.Single(m => m.Name == "None").Accessibility, Is.EqualTo(Accessibility.Private)); } private void AssertConstantField(ITypeDefinition type, string name, T expected) { var f = type.GetFields().Single(x => x.Name == name); - Assert.IsTrue(f.IsConst); - Assert.AreEqual(expected, f.GetConstantValue()); - Assert.AreEqual(0, f.GetAttributes().Count()); + Assert.That(f.IsConst); + Assert.That(f.GetConstantValue(), Is.EqualTo(expected)); + Assert.That(f.GetAttributes().Count(), Is.EqualTo(0)); } [Test] @@ -1589,8 +1586,8 @@ public void ConstantEnumFromThisAssembly() { ITypeDefinition type = GetTypeDefinition(typeof(ConstantFieldTest)); IField field = type.Fields.Single(f => f.Name == "EnumFromThisAssembly"); - Assert.IsTrue(field.IsConst); - Assert.AreEqual((short)MyEnum.Second, field.GetConstantValue()); + Assert.That(field.IsConst); + Assert.That(field.GetConstantValue(), Is.EqualTo((short)MyEnum.Second)); } [Test] @@ -1598,8 +1595,8 @@ public void ConstantEnumFromAnotherAssembly() { ITypeDefinition type = GetTypeDefinition(typeof(ConstantFieldTest)); IField field = type.Fields.Single(f => f.Name == "EnumFromAnotherAssembly"); - Assert.IsTrue(field.IsConst); - Assert.AreEqual((int)StringComparison.OrdinalIgnoreCase, field.GetConstantValue()); + Assert.That(field.IsConst); + Assert.That(field.GetConstantValue(), Is.EqualTo((int)StringComparison.OrdinalIgnoreCase)); } [Test] @@ -1607,8 +1604,8 @@ public void DefaultOfEnum() { ITypeDefinition type = GetTypeDefinition(typeof(ConstantFieldTest)); IField field = type.Fields.Single(f => f.Name == "DefaultOfEnum"); - Assert.IsTrue(field.IsConst); - Assert.AreEqual((short)default(MyEnum), field.GetConstantValue()); + Assert.That(field.IsConst); + Assert.That(field.GetConstantValue(), Is.EqualTo((short)default(MyEnum))); } [Test] @@ -1620,41 +1617,41 @@ public void ExplicitImplementation() var methods = type.GetMethods(m => m.Name == "M" || m.Name.EndsWith(".M")).ToList(); var imethod = itype.GetMethods(m => m.Name == "M").Single(); Assert.That(methods.Select(m => m.ExplicitlyImplementedInterfaceMembers.Count()).ToList(), Is.EquivalentTo(new[] { 0, 1 })); - Assert.AreEqual(methods.SelectMany(m => m.ExplicitlyImplementedInterfaceMembers).Single(), imethod); + Assert.That(imethod, Is.EqualTo(methods.SelectMany(m => m.ExplicitlyImplementedInterfaceMembers).Single())); var properties = type.GetProperties(p => p.Name == "P" || p.Name.EndsWith(".P")).ToList(); var iproperty = itype.GetProperties(m => m.Name == "P").Single(); Assert.That(properties.Select(p => p.ExplicitlyImplementedInterfaceMembers.Count()).ToList(), Is.EquivalentTo(new[] { 0, 1 })); - Assert.AreEqual(properties.SelectMany(p => p.ExplicitlyImplementedInterfaceMembers).Single(), iproperty); + Assert.That(iproperty, Is.EqualTo(properties.SelectMany(p => p.ExplicitlyImplementedInterfaceMembers).Single())); Assert.That(properties.Select(p => p.Getter.ExplicitlyImplementedInterfaceMembers.Count()).ToList(), Is.EquivalentTo(new[] { 0, 1 })); - Assert.AreEqual(properties.SelectMany(p => p.Getter.ExplicitlyImplementedInterfaceMembers).Single(), iproperty.Getter); + Assert.That(iproperty.Getter, Is.EqualTo(properties.SelectMany(p => p.Getter.ExplicitlyImplementedInterfaceMembers).Single())); Assert.That(properties.Select(p => p.Setter.ExplicitlyImplementedInterfaceMembers.Count()).ToList(), Is.EquivalentTo(new[] { 0, 1 })); - Assert.AreEqual(properties.SelectMany(p => p.Setter.ExplicitlyImplementedInterfaceMembers).Single(), iproperty.Setter); + Assert.That(iproperty.Setter, Is.EqualTo(properties.SelectMany(p => p.Setter.ExplicitlyImplementedInterfaceMembers).Single())); var indexers = type.GetProperties(p => p.Name == "Item" || p.Name.EndsWith(".Item")).ToList(); var iindexer = itype.GetProperties(m => m.Name == "Item").Single(); Assert.That(indexers.Select(p => p.ExplicitlyImplementedInterfaceMembers.Count()).ToList(), Is.EquivalentTo(new[] { 0, 1 })); - Assert.AreEqual(indexers.SelectMany(p => p.ExplicitlyImplementedInterfaceMembers).Single(), iindexer); + Assert.That(iindexer, Is.EqualTo(indexers.SelectMany(p => p.ExplicitlyImplementedInterfaceMembers).Single())); Assert.That(indexers.Select(p => p.Getter.ExplicitlyImplementedInterfaceMembers.Count()).ToList(), Is.EquivalentTo(new[] { 0, 1 })); - Assert.AreEqual(indexers.SelectMany(p => p.Getter.ExplicitlyImplementedInterfaceMembers).Single(), iindexer.Getter); + Assert.That(iindexer.Getter, Is.EqualTo(indexers.SelectMany(p => p.Getter.ExplicitlyImplementedInterfaceMembers).Single())); Assert.That(indexers.Select(p => p.Setter.ExplicitlyImplementedInterfaceMembers.Count()).ToList(), Is.EquivalentTo(new[] { 0, 1 })); - Assert.AreEqual(indexers.SelectMany(p => p.Setter.ExplicitlyImplementedInterfaceMembers).Single(), iindexer.Setter); + Assert.That(iindexer.Setter, Is.EqualTo(indexers.SelectMany(p => p.Setter.ExplicitlyImplementedInterfaceMembers).Single())); var events = type.GetEvents(e => e.Name == "E" || e.Name.EndsWith(".E")).ToList(); var ievent = itype.GetEvents(m => m.Name == "E").Single(); Assert.That(events.Select(e => e.ExplicitlyImplementedInterfaceMembers.Count()).ToList(), Is.EquivalentTo(new[] { 0, 1 })); - Assert.AreEqual(events.SelectMany(e => e.ExplicitlyImplementedInterfaceMembers).Single(), ievent); + Assert.That(ievent, Is.EqualTo(events.SelectMany(e => e.ExplicitlyImplementedInterfaceMembers).Single())); Assert.That(events.Select(e => e.AddAccessor.ExplicitlyImplementedInterfaceMembers.Count()).ToList(), Is.EquivalentTo(new[] { 0, 1 })); - Assert.AreEqual(events.SelectMany(e => e.AddAccessor.ExplicitlyImplementedInterfaceMembers).Single(), ievent.AddAccessor); + Assert.That(ievent.AddAccessor, Is.EqualTo(events.SelectMany(e => e.AddAccessor.ExplicitlyImplementedInterfaceMembers).Single())); Assert.That(events.Select(e => e.RemoveAccessor.ExplicitlyImplementedInterfaceMembers.Count()).ToList(), Is.EquivalentTo(new[] { 0, 1 })); - Assert.AreEqual(events.SelectMany(e => e.RemoveAccessor.ExplicitlyImplementedInterfaceMembers).Single(), ievent.RemoveAccessor); + Assert.That(ievent.RemoveAccessor, Is.EqualTo(events.SelectMany(e => e.RemoveAccessor.ExplicitlyImplementedInterfaceMembers).Single())); } [Test] public void MarshalTests() { ITypeDefinition c = compilation.FindType(typeof(IMarshalAsTests)).GetDefinition(); - Assert.AreEqual(1, c.GetMethods(m => m.Name == "GetCollectionByQuery2").Count()); + Assert.That(c.GetMethods(m => m.Name == "GetCollectionByQuery2").Count(), Is.EqualTo(1)); } @@ -1665,33 +1662,33 @@ public void AttributesUsingNestedMembers() var inner = type.GetNestedTypes().Single(t => t.Name == "Inner"); var myAttribute = type.GetNestedTypes().Single(t => t.Name == "MyAttribute"); var typeTypeTestAttr = type.GetAttributes().Single(a => a.AttributeType.Name == "TypeTestAttribute"); - Assert.AreEqual(42, typeTypeTestAttr.FixedArguments[0].Value); - Assert.AreEqual(inner, typeTypeTestAttr.FixedArguments[1].Value); + Assert.That(typeTypeTestAttr.FixedArguments[0].Value, Is.EqualTo(42)); + Assert.That(typeTypeTestAttr.FixedArguments[1].Value, Is.EqualTo(inner)); var typeMyAttr = type.GetAttributes().Single(a => a.AttributeType.Name == "MyAttribute"); - Assert.AreEqual(myAttribute, typeMyAttr.AttributeType); + Assert.That(typeMyAttr.AttributeType, Is.EqualTo(myAttribute)); var prop = type.GetProperties().Single(p => p.Name == "P"); var propTypeTestAttr = prop.GetAttributes().Single(a => a.AttributeType.Name == "TypeTestAttribute"); - Assert.AreEqual(42, propTypeTestAttr.FixedArguments[0].Value); - Assert.AreEqual(inner, propTypeTestAttr.FixedArguments[1].Value); + Assert.That(propTypeTestAttr.FixedArguments[0].Value, Is.EqualTo(42)); + Assert.That(propTypeTestAttr.FixedArguments[1].Value, Is.EqualTo(inner)); var propMyAttr = prop.GetAttributes().Single(a => a.AttributeType.Name == "MyAttribute"); - Assert.AreEqual(myAttribute, propMyAttr.AttributeType); + Assert.That(propMyAttr.AttributeType, Is.EqualTo(myAttribute)); var attributedInner = (ITypeDefinition)type.GetNestedTypes().Single(t => t.Name == "AttributedInner"); var innerTypeTestAttr = attributedInner.GetAttributes().Single(a => a.AttributeType.Name == "TypeTestAttribute"); - Assert.AreEqual(42, innerTypeTestAttr.FixedArguments[0].Value); - Assert.AreEqual(inner, innerTypeTestAttr.FixedArguments[1].Value); + Assert.That(innerTypeTestAttr.FixedArguments[0].Value, Is.EqualTo(42)); + Assert.That(innerTypeTestAttr.FixedArguments[1].Value, Is.EqualTo(inner)); var innerMyAttr = attributedInner.GetAttributes().Single(a => a.AttributeType.Name == "MyAttribute"); - Assert.AreEqual(myAttribute, innerMyAttr.AttributeType); + Assert.That(innerMyAttr.AttributeType, Is.EqualTo(myAttribute)); var attributedInner2 = (ITypeDefinition)type.GetNestedTypes().Single(t => t.Name == "AttributedInner2"); var inner2 = attributedInner2.GetNestedTypes().Single(t => t.Name == "Inner"); var myAttribute2 = attributedInner2.GetNestedTypes().Single(t => t.Name == "MyAttribute"); var inner2TypeTestAttr = attributedInner2.GetAttributes().Single(a => a.AttributeType.Name == "TypeTestAttribute"); - Assert.AreEqual(43, inner2TypeTestAttr.FixedArguments[0].Value); - Assert.AreEqual(inner2, inner2TypeTestAttr.FixedArguments[1].Value); + Assert.That(inner2TypeTestAttr.FixedArguments[0].Value, Is.EqualTo(43)); + Assert.That(inner2TypeTestAttr.FixedArguments[1].Value, Is.EqualTo(inner2)); var inner2MyAttr = attributedInner2.GetAttributes().Single(a => a.AttributeType.Name == "MyAttribute"); - Assert.AreEqual(myAttribute2, inner2MyAttr.AttributeType); + Assert.That(inner2MyAttr.AttributeType, Is.EqualTo(myAttribute2)); } [Test] @@ -1699,7 +1696,7 @@ public void ClassWithAttributeOnTypeParameter() { var tp = GetTypeDefinition(typeof(ClassWithAttributeOnTypeParameter<>)).TypeParameters.Single(); var attr = tp.GetAttributes().Single(); - Assert.AreEqual("DoubleAttribute", attr.AttributeType.Name); + Assert.That(attr.AttributeType.Name, Is.EqualTo("DoubleAttribute")); } [Test] @@ -1707,19 +1704,19 @@ public void InheritanceTest() { ITypeDefinition c = compilation.FindType(typeof(SystemException)).GetDefinition(); ITypeDefinition c2 = compilation.FindType(typeof(Exception)).GetDefinition(); - Assert.IsNotNull(c, "c is null"); - Assert.IsNotNull(c2, "c2 is null"); + Assert.That(c, Is.Not.Null, "c is null"); + Assert.That(c2, Is.Not.Null, "c2 is null"); //Assert.AreEqual(3, c.BaseTypes.Count); // Inherited interfaces are not reported by Cecil // which matches the behaviour of our C#/VB parsers - Assert.AreEqual("System.Exception", c.DirectBaseTypes.First().FullName); - Assert.AreSame(c2, c.DirectBaseTypes.First()); + Assert.That(c.DirectBaseTypes.First().FullName, Is.EqualTo("System.Exception")); + Assert.That(c.DirectBaseTypes.First(), Is.SameAs(c2)); string[] superTypes = c.GetAllBaseTypes().Select(t => t.ReflectionName).ToArray(); - Assert.AreEqual(new string[] { + Assert.That(superTypes, Is.EqualTo(new string[] { "System.Object", "System.Runtime.Serialization.ISerializable", "System.Runtime.InteropServices._Exception", "System.Exception", "System.SystemException" - }, superTypes); + })); } [Test] @@ -1728,8 +1725,8 @@ public void GenericPropertyTest() ITypeDefinition c = compilation.FindType(typeof(Comparer<>)).GetDefinition(); IProperty def = c.Properties.Single(p => p.Name == "Default"); ParameterizedType pt = (ParameterizedType)def.ReturnType; - Assert.AreEqual("System.Collections.Generic.Comparer", pt.FullName); - Assert.AreEqual(c.TypeParameters[0], pt.TypeArguments[0]); + Assert.That(pt.FullName, Is.EqualTo("System.Collections.Generic.Comparer")); + Assert.That(pt.TypeArguments[0], Is.EqualTo(c.TypeParameters[0])); } [Test] @@ -1737,17 +1734,17 @@ public void PointerTypeTest() { ITypeDefinition c = compilation.FindType(typeof(IntPtr)).GetDefinition(); IMethod toPointer = c.Methods.Single(p => p.Name == "ToPointer"); - Assert.AreEqual("System.Void*", toPointer.ReturnType.ReflectionName); - Assert.IsTrue(toPointer.ReturnType is PointerType); - Assert.AreEqual("System.Void", ((PointerType)toPointer.ReturnType).ElementType.FullName); + Assert.That(toPointer.ReturnType.ReflectionName, Is.EqualTo("System.Void*")); + Assert.That(toPointer.ReturnType is PointerType); + Assert.That(((PointerType)toPointer.ReturnType).ElementType.FullName, Is.EqualTo("System.Void")); } [Test] public void DateTimeDefaultConstructor() { ITypeDefinition c = compilation.FindType(typeof(DateTime)).GetDefinition(); - Assert.AreEqual(1, c.Methods.Count(m => m.IsConstructor && !m.IsStatic && m.Parameters.Count == 0)); - Assert.AreEqual(1, c.GetConstructors().Count(m => m.Parameters.Count == 0)); + Assert.That(c.Methods.Count(m => m.IsConstructor && !m.IsStatic && m.Parameters.Count == 0), Is.EqualTo(1)); + Assert.That(c.GetConstructors().Count(m => m.Parameters.Count == 0), Is.EqualTo(1)); } [Test] @@ -1755,49 +1752,49 @@ public void NoEncodingInfoDefaultConstructor() { ITypeDefinition c = compilation.FindType(typeof(EncodingInfo)).GetDefinition(); // EncodingInfo only has an internal constructor - Assert.IsFalse(c.Methods.Any(m => m.IsConstructor)); + Assert.That(!c.Methods.Any(m => m.IsConstructor)); // and no implicit ctor should be added: - Assert.AreEqual(0, c.GetConstructors().Count()); + Assert.That(c.GetConstructors().Count(), Is.EqualTo(0)); } [Test] public void StaticModifierTest() { ITypeDefinition c = compilation.FindType(typeof(Environment)).GetDefinition(); - Assert.IsNotNull(c, "System.Environment not found"); - Assert.IsTrue(c.IsAbstract, "class should be abstract"); - Assert.IsTrue(c.IsSealed, "class should be sealed"); - Assert.IsTrue(c.IsStatic, "class should be static"); + Assert.That(c, Is.Not.Null, "System.Environment not found"); + Assert.That(c.IsAbstract, "class should be abstract"); + Assert.That(c.IsSealed, "class should be sealed"); + Assert.That(c.IsStatic, "class should be static"); } [Test] public void InnerClassReferenceTest() { ITypeDefinition c = compilation.FindType(typeof(Environment)).GetDefinition(); - Assert.IsNotNull(c, "System.Environment not found"); + Assert.That(c, Is.Not.Null, "System.Environment not found"); IType rt = c.Methods.First(m => m.Name == "GetFolderPath").Parameters[0].Type; - Assert.AreSame(c.NestedTypes.Single(ic => ic.Name == "SpecialFolder"), rt); + Assert.That(rt, Is.SameAs(c.NestedTypes.Single(ic => ic.Name == "SpecialFolder"))); } [Test] public void NestedTypesTest() { ITypeDefinition c = compilation.FindType(typeof(Environment.SpecialFolder)).GetDefinition(); - Assert.IsNotNull(c, "c is null"); - Assert.AreEqual("System.Environment.SpecialFolder", c.FullName); - Assert.AreEqual("System.Environment+SpecialFolder", c.ReflectionName); + Assert.That(c, Is.Not.Null, "c is null"); + Assert.That(c.FullName, Is.EqualTo("System.Environment.SpecialFolder")); + Assert.That(c.ReflectionName, Is.EqualTo("System.Environment+SpecialFolder")); } [Test] public void VoidHasNoMembers() { ITypeDefinition c = compilation.FindType(typeof(void)).GetDefinition(); - Assert.IsNotNull(c, "System.Void not found"); - Assert.AreEqual(TypeKind.Void, c.Kind); - Assert.AreEqual(0, c.GetMethods().Count()); - Assert.AreEqual(0, c.GetProperties().Count()); - Assert.AreEqual(0, c.GetEvents().Count()); - Assert.AreEqual(0, c.GetFields().Count()); + Assert.That(c, Is.Not.Null, "System.Void not found"); + Assert.That(c.Kind, Is.EqualTo(TypeKind.Void)); + Assert.That(c.GetMethods().Count(), Is.EqualTo(0)); + Assert.That(c.GetProperties().Count(), Is.EqualTo(0)); + Assert.That(c.GetEvents().Count(), Is.EqualTo(0)); + Assert.That(c.GetFields().Count(), Is.EqualTo(0)); } [Test] @@ -1805,9 +1802,9 @@ public void Void_SerializableAttribute() { ITypeDefinition c = compilation.FindType(typeof(void)).GetDefinition(); var attr = c.GetAttributes().Single(a => a.AttributeType.FullName == "System.SerializableAttribute"); - Assert.AreEqual(0, attr.Constructor.Parameters.Count); - Assert.AreEqual(0, attr.FixedArguments.Length); - Assert.AreEqual(0, attr.NamedArguments.Length); + Assert.That(attr.Constructor.Parameters.Count, Is.EqualTo(0)); + Assert.That(attr.FixedArguments.Length, Is.EqualTo(0)); + Assert.That(attr.NamedArguments.Length, Is.EqualTo(0)); } [Test] @@ -1815,12 +1812,12 @@ public void Void_StructLayoutAttribute() { ITypeDefinition c = compilation.FindType(typeof(void)).GetDefinition(); var attr = c.GetAttributes().Single(a => a.AttributeType.FullName == "System.Runtime.InteropServices.StructLayoutAttribute"); - Assert.AreEqual(1, attr.Constructor.Parameters.Count); - Assert.AreEqual(1, attr.FixedArguments.Length); - Assert.AreEqual(0, attr.FixedArguments[0].Value); - Assert.AreEqual(1, attr.NamedArguments.Length); - Assert.AreEqual("Size", attr.NamedArguments[0].Name); - Assert.AreEqual(1, attr.NamedArguments[0].Value); + Assert.That(attr.Constructor.Parameters.Count, Is.EqualTo(1)); + Assert.That(attr.FixedArguments.Length, Is.EqualTo(1)); + Assert.That(attr.FixedArguments[0].Value, Is.EqualTo(0)); + Assert.That(attr.NamedArguments.Length, Is.EqualTo(1)); + Assert.That(attr.NamedArguments[0].Name, Is.EqualTo("Size")); + Assert.That(attr.NamedArguments[0].Value, Is.EqualTo(1)); } [Test] @@ -1828,126 +1825,126 @@ public void Void_ComVisibleAttribute() { ITypeDefinition c = compilation.FindType(typeof(void)).GetDefinition(); var attr = c.GetAttributes().Single(a => a.AttributeType.FullName == "System.Runtime.InteropServices.ComVisibleAttribute"); - Assert.AreEqual(1, attr.Constructor.Parameters.Count); - Assert.AreEqual(1, attr.FixedArguments.Length); - Assert.AreEqual(true, attr.FixedArguments[0].Value); - Assert.AreEqual(0, attr.NamedArguments.Length); + Assert.That(attr.Constructor.Parameters.Count, Is.EqualTo(1)); + Assert.That(attr.FixedArguments.Length, Is.EqualTo(1)); + Assert.That(attr.FixedArguments[0].Value, Is.EqualTo(true)); + Assert.That(attr.NamedArguments.Length, Is.EqualTo(0)); } [Test] public void NestedClassInGenericClassTest() { ITypeDefinition dictionary = compilation.FindType(typeof(Dictionary<,>)).GetDefinition(); - Assert.IsNotNull(dictionary); + Assert.That(dictionary, Is.Not.Null); ITypeDefinition valueCollection = compilation.FindType(typeof(Dictionary<,>.ValueCollection)).GetDefinition(); - Assert.IsNotNull(valueCollection); + Assert.That(valueCollection, Is.Not.Null); var dictionaryRT = new ParameterizedType(dictionary, new[] { compilation.FindType(typeof(string)).GetDefinition(), compilation.FindType(typeof(int)).GetDefinition() }); IProperty valueProperty = dictionaryRT.GetProperties(p => p.Name == "Values").Single(); IType parameterizedValueCollection = valueProperty.ReturnType; - Assert.AreEqual("System.Collections.Generic.Dictionary`2+ValueCollection[[System.String],[System.Int32]]", parameterizedValueCollection.ReflectionName); - Assert.AreSame(valueCollection, parameterizedValueCollection.GetDefinition()); + Assert.That(parameterizedValueCollection.ReflectionName, Is.EqualTo("System.Collections.Generic.Dictionary`2+ValueCollection[[System.String],[System.Int32]]")); + Assert.That(parameterizedValueCollection.GetDefinition(), Is.SameAs(valueCollection)); } [Test] public void ValueCollectionCountModifiers() { ITypeDefinition valueCollection = compilation.FindType(typeof(Dictionary<,>.ValueCollection)).GetDefinition(); - Assert.AreEqual(Accessibility.Public, valueCollection.Accessibility); - Assert.IsTrue(valueCollection.IsSealed); - Assert.IsFalse(valueCollection.IsAbstract); - Assert.IsFalse(valueCollection.IsStatic); + Assert.That(valueCollection.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(valueCollection.IsSealed); + Assert.That(!valueCollection.IsAbstract); + Assert.That(!valueCollection.IsStatic); IProperty count = valueCollection.Properties.Single(p => p.Name == "Count"); - Assert.AreEqual(Accessibility.Public, count.Accessibility); + Assert.That(count.Accessibility, Is.EqualTo(Accessibility.Public)); // It's sealed on the IL level; but in C# it's just a normal non-virtual method that happens to implement an interface - Assert.IsFalse(count.IsSealed); - Assert.IsFalse(count.IsVirtual); - Assert.IsFalse(count.IsAbstract); + Assert.That(!count.IsSealed); + Assert.That(!count.IsVirtual); + Assert.That(!count.IsAbstract); } [Test] public void MathAcosModifiers() { ITypeDefinition math = compilation.FindType(typeof(Math)).GetDefinition(); - Assert.AreEqual(Accessibility.Public, math.Accessibility); - Assert.IsTrue(math.IsSealed); - Assert.IsTrue(math.IsAbstract); - Assert.IsTrue(math.IsStatic); + Assert.That(math.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(math.IsSealed); + Assert.That(math.IsAbstract); + Assert.That(math.IsStatic); IMethod acos = math.Methods.Single(p => p.Name == "Acos"); - Assert.AreEqual(Accessibility.Public, acos.Accessibility); - Assert.IsTrue(acos.IsStatic); - Assert.IsFalse(acos.IsAbstract); - Assert.IsFalse(acos.IsSealed); - Assert.IsFalse(acos.IsVirtual); - Assert.IsFalse(acos.IsOverride); + Assert.That(acos.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(acos.IsStatic); + Assert.That(!acos.IsAbstract); + Assert.That(!acos.IsSealed); + Assert.That(!acos.IsVirtual); + Assert.That(!acos.IsOverride); } [Test] public void EncodingModifiers() { ITypeDefinition encoding = compilation.FindType(typeof(Encoding)).GetDefinition(); - Assert.AreEqual(Accessibility.Public, encoding.Accessibility); - Assert.IsFalse(encoding.IsSealed); - Assert.IsTrue(encoding.IsAbstract); + Assert.That(encoding.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(!encoding.IsSealed); + Assert.That(encoding.IsAbstract); IMethod getDecoder = encoding.Methods.Single(p => p.Name == "GetDecoder"); - Assert.AreEqual(Accessibility.Public, getDecoder.Accessibility); - Assert.IsFalse(getDecoder.IsStatic); - Assert.IsFalse(getDecoder.IsAbstract); - Assert.IsFalse(getDecoder.IsSealed); - Assert.IsTrue(getDecoder.IsVirtual); - Assert.IsFalse(getDecoder.IsOverride); + Assert.That(getDecoder.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(!getDecoder.IsStatic); + Assert.That(!getDecoder.IsAbstract); + Assert.That(!getDecoder.IsSealed); + Assert.That(getDecoder.IsVirtual); + Assert.That(!getDecoder.IsOverride); IMethod getMaxByteCount = encoding.Methods.Single(p => p.Name == "GetMaxByteCount"); - Assert.AreEqual(Accessibility.Public, getMaxByteCount.Accessibility); - Assert.IsFalse(getMaxByteCount.IsStatic); - Assert.IsTrue(getMaxByteCount.IsAbstract); - Assert.IsFalse(getMaxByteCount.IsSealed); - Assert.IsFalse(getMaxByteCount.IsVirtual); - Assert.IsFalse(getMaxByteCount.IsOverride); + Assert.That(getMaxByteCount.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(!getMaxByteCount.IsStatic); + Assert.That(getMaxByteCount.IsAbstract); + Assert.That(!getMaxByteCount.IsSealed); + Assert.That(!getMaxByteCount.IsVirtual); + Assert.That(!getMaxByteCount.IsOverride); IProperty encoderFallback = encoding.Properties.Single(p => p.Name == "EncoderFallback"); - Assert.AreEqual(Accessibility.Public, encoderFallback.Accessibility); - Assert.IsFalse(encoderFallback.IsStatic); - Assert.IsFalse(encoderFallback.IsAbstract); - Assert.IsFalse(encoderFallback.IsSealed); - Assert.IsFalse(encoderFallback.IsVirtual); - Assert.IsFalse(encoderFallback.IsOverride); + Assert.That(encoderFallback.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(!encoderFallback.IsStatic); + Assert.That(!encoderFallback.IsAbstract); + Assert.That(!encoderFallback.IsSealed); + Assert.That(!encoderFallback.IsVirtual); + Assert.That(!encoderFallback.IsOverride); } [Test] public void UnicodeEncodingModifiers() { ITypeDefinition encoding = compilation.FindType(typeof(UnicodeEncoding)).GetDefinition(); - Assert.AreEqual(Accessibility.Public, encoding.Accessibility); - Assert.IsFalse(encoding.IsSealed); - Assert.IsFalse(encoding.IsAbstract); + Assert.That(encoding.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(!encoding.IsSealed); + Assert.That(!encoding.IsAbstract); IMethod getDecoder = encoding.Methods.Single(p => p.Name == "GetDecoder"); - Assert.AreEqual(Accessibility.Public, getDecoder.Accessibility); - Assert.IsFalse(getDecoder.IsStatic); - Assert.IsFalse(getDecoder.IsAbstract); - Assert.IsFalse(getDecoder.IsSealed); - Assert.IsFalse(getDecoder.IsVirtual); - Assert.IsTrue(getDecoder.IsOverride); + Assert.That(getDecoder.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(!getDecoder.IsStatic); + Assert.That(!getDecoder.IsAbstract); + Assert.That(!getDecoder.IsSealed); + Assert.That(!getDecoder.IsVirtual); + Assert.That(getDecoder.IsOverride); } [Test] public void UTF32EncodingModifiers() { ITypeDefinition encoding = compilation.FindType(typeof(UTF32Encoding)).GetDefinition(); - Assert.AreEqual(Accessibility.Public, encoding.Accessibility); - Assert.IsTrue(encoding.IsSealed); - Assert.IsFalse(encoding.IsAbstract); + Assert.That(encoding.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(encoding.IsSealed); + Assert.That(!encoding.IsAbstract); IMethod getDecoder = encoding.Methods.Single(p => p.Name == "GetDecoder"); - Assert.AreEqual(Accessibility.Public, getDecoder.Accessibility); - Assert.IsFalse(getDecoder.IsStatic); - Assert.IsFalse(getDecoder.IsAbstract); - Assert.IsFalse(getDecoder.IsSealed); - Assert.IsFalse(getDecoder.IsVirtual); - Assert.IsTrue(getDecoder.IsOverride); + Assert.That(getDecoder.Accessibility, Is.EqualTo(Accessibility.Public)); + Assert.That(!getDecoder.IsStatic); + Assert.That(!getDecoder.IsAbstract); + Assert.That(!getDecoder.IsSealed); + Assert.That(!getDecoder.IsVirtual); + Assert.That(getDecoder.IsOverride); } [Test] @@ -1957,22 +1954,22 @@ public void FindRedirectedType() var typeRef = ReflectionHelper.ParseReflectionName("System.Func`2, System.Core"); ITypeDefinition c = typeRef.Resolve(new SimpleTypeResolveContext(compilationWithSystemCore)).GetDefinition(); - Assert.IsNotNull(c, "System.Func<,> not found"); - Assert.AreEqual("mscorlib", c.ParentModule.AssemblyName); + Assert.That(c, Is.Not.Null, "System.Func<,> not found"); + Assert.That(c.ParentModule.AssemblyName, Is.EqualTo("mscorlib")); } public void DelegateIsClass() { var @delegate = compilation.FindType(KnownTypeCode.Delegate).GetDefinition(); - Assert.AreEqual(TypeKind.Class, @delegate); - Assert.IsFalse(@delegate.IsSealed); + Assert.That(@delegate, Is.EqualTo(TypeKind.Class)); + Assert.That(!@delegate.IsSealed); } public void MulticastDelegateIsClass() { var multicastDelegate = compilation.FindType(KnownTypeCode.MulticastDelegate).GetDefinition(); - Assert.AreEqual(TypeKind.Class, multicastDelegate); - Assert.IsFalse(multicastDelegate.IsSealed); + Assert.That(multicastDelegate, Is.EqualTo(TypeKind.Class)); + Assert.That(!multicastDelegate.IsSealed); } [Test] @@ -1988,13 +1985,13 @@ public void HasSpecialName() var @class = nonCustomAttributes.GetNestedTypes(t => t.Name == "SpecialNameClass").Single().GetDefinition(); var @struct = nonCustomAttributes.GetNestedTypes(t => t.Name == "SpecialNameStruct").Single().GetDefinition(); - Assert.IsTrue(method.HasAttribute(KnownAttribute.SpecialName)); - Assert.IsTrue(property.HasAttribute(KnownAttribute.SpecialName)); - Assert.IsTrue(@event.HasAttribute(KnownAttribute.SpecialName)); - Assert.IsTrue(field.HasAttribute(KnownAttribute.SpecialName)); + Assert.That(method.HasAttribute(KnownAttribute.SpecialName)); + Assert.That(property.HasAttribute(KnownAttribute.SpecialName)); + Assert.That(@event.HasAttribute(KnownAttribute.SpecialName)); + Assert.That(field.HasAttribute(KnownAttribute.SpecialName)); - Assert.IsTrue(@class.HasAttribute(KnownAttribute.SpecialName)); - Assert.IsTrue(@struct.HasAttribute(KnownAttribute.SpecialName)); + Assert.That(@class.HasAttribute(KnownAttribute.SpecialName)); + Assert.That(@struct.HasAttribute(KnownAttribute.SpecialName)); } } } diff --git a/ICSharpCode.Decompiler.Tests/UglyTestRunner.cs b/ICSharpCode.Decompiler.Tests/UglyTestRunner.cs index 1e2cceb6c5..620424ca85 100644 --- a/ICSharpCode.Decompiler.Tests/UglyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/UglyTestRunner.cs @@ -47,7 +47,7 @@ public void AllFilesHaveTests() || file.Extension.Equals(".cs", StringComparison.OrdinalIgnoreCase)) { var testName = file.Name.Split('.')[0]; - Assert.Contains(testName, testNames); + Assert.That(testNames, Has.Member(testName)); } } } diff --git a/ICSharpCode.Decompiler.Tests/Util/BitSetTests.cs b/ICSharpCode.Decompiler.Tests/Util/BitSetTests.cs index 8f22676bbb..a7c5b3dc3c 100644 --- a/ICSharpCode.Decompiler.Tests/Util/BitSetTests.cs +++ b/ICSharpCode.Decompiler.Tests/Util/BitSetTests.cs @@ -30,13 +30,13 @@ public void SetRange() { var bitset = new BitSet(302); bitset.Set(2, 300); - Assert.IsFalse(bitset[0]); - Assert.IsFalse(bitset[1]); + Assert.That(!bitset[0]); + Assert.That(!bitset[1]); for (int i = 2; i < 300; ++i) { - Assert.IsTrue(bitset[i]); + Assert.That(bitset[i]); } - Assert.IsFalse(bitset[301]); + Assert.That(!bitset[301]); } [Test] @@ -45,12 +45,12 @@ public void ClearRange() var bitset = new BitSet(300); bitset.Set(0, 300); bitset.Clear(1, 299); - Assert.IsTrue(bitset[0]); + Assert.That(bitset[0]); for (int i = 1; i < 299; ++i) { - Assert.IsFalse(bitset[i]); + Assert.That(!bitset[i]); } - Assert.IsTrue(bitset[299]); + Assert.That(bitset[299]); } [Test] @@ -58,14 +58,30 @@ public void AllInRange() { var bitset = new BitSet(300); bitset.Set(1, 299); - Assert.IsTrue(bitset.All(1, 299)); - Assert.IsTrue(bitset.All(10, 290)); - Assert.IsTrue(bitset.All(100, 200)); - Assert.IsFalse(bitset.All(0, 200)); - Assert.IsFalse(bitset.All(0, 1)); - Assert.IsFalse(bitset.All(1, 300)); + Assert.That(bitset.All(1, 299)); + Assert.That(bitset.All(10, 290)); + Assert.That(bitset.All(100, 200)); + Assert.That(!bitset.All(0, 200)); + Assert.That(!bitset.All(0, 1)); + Assert.That(!bitset.All(1, 300)); bitset[200] = false; - Assert.IsFalse(bitset.All(1, 299)); + Assert.That(!bitset.All(1, 299)); + } + + [Test] + public void NextBitSet() + { + var bitset = new BitSet(300); + bitset.Set(0); + bitset.Set(2); + bitset.Set(3); + bitset.Set(130); + bitset.Set(135); + bitset.Set(150); + bitset.Set(190); + Assert.That(bitset.SetBits(0, 300), Is.EqualTo(new[] { 0, 2, 3, 130, 135, 150, 190 })); + Assert.That(bitset.SetBits(1, 5), Is.EqualTo(new[] { 2, 3 })); + Assert.That(bitset.SetBits(5, 132), Is.EqualTo(new[] { 130 })); } } } diff --git a/ICSharpCode.Decompiler.Tests/Util/FileUtilityTests.cs b/ICSharpCode.Decompiler.Tests/Util/FileUtilityTests.cs index e188f94780..19f8ea5e49 100644 --- a/ICSharpCode.Decompiler.Tests/Util/FileUtilityTests.cs +++ b/ICSharpCode.Decompiler.Tests/Util/FileUtilityTests.cs @@ -29,157 +29,157 @@ public class FileUtilityTests [Test] public void NormalizePath() { - Assert.AreEqual(@"c:\temp\test.txt", FileUtility.NormalizePath(@"c:\temp\project\..\test.txt")); - Assert.AreEqual(@"c:\temp\test.txt", FileUtility.NormalizePath(@"c:\temp\project\.\..\test.txt")); - Assert.AreEqual(@"c:\temp\test.txt", FileUtility.NormalizePath(@"c:\temp\\test.txt")); // normalize double backslash - Assert.AreEqual(@"c:\temp", FileUtility.NormalizePath(@"c:\temp\.")); - Assert.AreEqual(@"c:\temp", FileUtility.NormalizePath(@"c:\temp\subdir\..")); + Assert.That(FileUtility.NormalizePath(@"c:\temp\project\..\test.txt"), Is.EqualTo(@"c:\temp\test.txt")); + Assert.That(FileUtility.NormalizePath(@"c:\temp\project\.\..\test.txt"), Is.EqualTo(@"c:\temp\test.txt")); + Assert.That(FileUtility.NormalizePath(@"c:\temp\\test.txt"), Is.EqualTo(@"c:\temp\test.txt")); // normalize double backslash + Assert.That(FileUtility.NormalizePath(@"c:\temp\."), Is.EqualTo(@"c:\temp")); + Assert.That(FileUtility.NormalizePath(@"c:\temp\subdir\.."), Is.EqualTo(@"c:\temp")); } [Test] public void NormalizePath_DriveRoot() { - Assert.AreEqual(@"C:\", FileUtility.NormalizePath(@"C:\")); - Assert.AreEqual(@"C:\", FileUtility.NormalizePath(@"C:/")); - Assert.AreEqual(@"C:\", FileUtility.NormalizePath(@"C:")); - Assert.AreEqual(@"C:\", FileUtility.NormalizePath(@"C:/.")); - Assert.AreEqual(@"C:\", FileUtility.NormalizePath(@"C:/..")); - Assert.AreEqual(@"C:\", FileUtility.NormalizePath(@"C:/./")); - Assert.AreEqual(@"C:\", FileUtility.NormalizePath(@"C:/..\")); + Assert.That(FileUtility.NormalizePath(@"C:\"), Is.EqualTo(@"C:\")); + Assert.That(FileUtility.NormalizePath(@"C:/"), Is.EqualTo(@"C:\")); + Assert.That(FileUtility.NormalizePath(@"C:"), Is.EqualTo(@"C:\")); + Assert.That(FileUtility.NormalizePath(@"C:/."), Is.EqualTo(@"C:\")); + Assert.That(FileUtility.NormalizePath(@"C:/.."), Is.EqualTo(@"C:\")); + Assert.That(FileUtility.NormalizePath(@"C:/./"), Is.EqualTo(@"C:\")); + Assert.That(FileUtility.NormalizePath(@"C:/..\"), Is.EqualTo(@"C:\")); } [Test] public void NormalizePath_UNC() { - Assert.AreEqual(@"\\server\share", FileUtility.NormalizePath(@"\\server\share")); - Assert.AreEqual(@"\\server\share", FileUtility.NormalizePath(@"\\server\share\")); - Assert.AreEqual(@"\\server\share", FileUtility.NormalizePath(@"//server/share/")); - Assert.AreEqual(@"\\server\share\otherdir", FileUtility.NormalizePath(@"//server/share/dir/..\otherdir")); + Assert.That(FileUtility.NormalizePath(@"\\server\share"), Is.EqualTo(@"\\server\share")); + Assert.That(FileUtility.NormalizePath(@"\\server\share\"), Is.EqualTo(@"\\server\share")); + Assert.That(FileUtility.NormalizePath(@"//server/share/"), Is.EqualTo(@"\\server\share")); + Assert.That(FileUtility.NormalizePath(@"//server/share/dir/..\otherdir"), Is.EqualTo(@"\\server\share\otherdir")); } [Test] public void NormalizePath_Web() { - Assert.AreEqual(@"http://danielgrunwald.de/path/", FileUtility.NormalizePath(@"http://danielgrunwald.de/path/")); - Assert.AreEqual(@"browser://http://danielgrunwald.de/path/", FileUtility.NormalizePath(@"browser://http://danielgrunwald.de/wrongpath/../path/")); + Assert.That(FileUtility.NormalizePath(@"http://danielgrunwald.de/path/"), Is.EqualTo(@"http://danielgrunwald.de/path/")); + Assert.That(FileUtility.NormalizePath(@"browser://http://danielgrunwald.de/wrongpath/../path/"), Is.EqualTo(@"browser://http://danielgrunwald.de/path/")); } [Test] public void NormalizePath_Relative() { - Assert.AreEqual(@"../b", FileUtility.NormalizePath(@"..\a\..\b")); - Assert.AreEqual(@".", FileUtility.NormalizePath(@".")); - Assert.AreEqual(@".", FileUtility.NormalizePath(@"a\..")); + Assert.That(FileUtility.NormalizePath(@"..\a\..\b"), Is.EqualTo(@"../b")); + Assert.That(FileUtility.NormalizePath(@"."), Is.EqualTo(@".")); + Assert.That(FileUtility.NormalizePath(@"a\.."), Is.EqualTo(@".")); } [Test] public void NormalizePath_UnixStyle() { - Assert.AreEqual("/", FileUtility.NormalizePath("/")); - Assert.AreEqual("/a/b", FileUtility.NormalizePath("/a/b")); - Assert.AreEqual("/a/b", FileUtility.NormalizePath("/c/../a/./b")); - Assert.AreEqual("/a/b", FileUtility.NormalizePath("/c/../../a/./b")); + Assert.That(FileUtility.NormalizePath("/"), Is.EqualTo("/")); + Assert.That(FileUtility.NormalizePath("/a/b"), Is.EqualTo("/a/b")); + Assert.That(FileUtility.NormalizePath("/c/../a/./b"), Is.EqualTo("/a/b")); + Assert.That(FileUtility.NormalizePath("/c/../../a/./b"), Is.EqualTo("/a/b")); } #endregion [Test] public void TestIsBaseDirectory() { - Assert.IsTrue(FileUtility.IsBaseDirectory(@"C:\a", @"C:\A\b\hello")); - Assert.IsTrue(FileUtility.IsBaseDirectory(@"C:\a", @"C:\a")); - Assert.IsTrue(FileUtility.IsBaseDirectory(@"C:\a\", @"C:\a\")); - Assert.IsTrue(FileUtility.IsBaseDirectory(@"C:\a\", @"C:\a")); - Assert.IsTrue(FileUtility.IsBaseDirectory(@"C:\a", @"C:\a\")); - Assert.IsTrue(FileUtility.IsBaseDirectory(@"C:\A", @"C:\a")); - Assert.IsTrue(FileUtility.IsBaseDirectory(@"C:\a", @"C:\A")); - Assert.IsTrue(FileUtility.IsBaseDirectory(@"C:\a\x\fWufhweoe", @"C:\a\x\fwuFHweoe\a\b\hello")); - - Assert.IsTrue(FileUtility.IsBaseDirectory(@"C:\b\..\A", @"C:\a")); - Assert.IsTrue(FileUtility.IsBaseDirectory(@"C:\HELLO\..\B\..\a", @"C:\b\..\a")); - Assert.IsTrue(FileUtility.IsBaseDirectory(@"C:\.\B\..\.\.\a", @"C:\.\.\.\.\.\.\.\a")); - - Assert.IsFalse(FileUtility.IsBaseDirectory(@"C:\b", @"C:\a\b\hello")); - Assert.IsFalse(FileUtility.IsBaseDirectory(@"C:\a\b\hello", @"C:\b")); - Assert.IsFalse(FileUtility.IsBaseDirectory(@"C:\a\x\fwufhweoe", @"C:\a\x\fwuFHweoex\a\b\hello")); - Assert.IsTrue(FileUtility.IsBaseDirectory(@"C:\", @"C:\")); - Assert.IsTrue(FileUtility.IsBaseDirectory(@"C:\", @"C:\a\b\hello")); - Assert.IsFalse(FileUtility.IsBaseDirectory(@"C:\", @"D:\a\b\hello")); + Assert.That(FileUtility.IsBaseDirectory(@"C:\a", @"C:\A\b\hello")); + Assert.That(FileUtility.IsBaseDirectory(@"C:\a", @"C:\a")); + Assert.That(FileUtility.IsBaseDirectory(@"C:\a\", @"C:\a\")); + Assert.That(FileUtility.IsBaseDirectory(@"C:\a\", @"C:\a")); + Assert.That(FileUtility.IsBaseDirectory(@"C:\a", @"C:\a\")); + Assert.That(FileUtility.IsBaseDirectory(@"C:\A", @"C:\a")); + Assert.That(FileUtility.IsBaseDirectory(@"C:\a", @"C:\A")); + Assert.That(FileUtility.IsBaseDirectory(@"C:\a\x\fWufhweoe", @"C:\a\x\fwuFHweoe\a\b\hello")); + + Assert.That(FileUtility.IsBaseDirectory(@"C:\b\..\A", @"C:\a")); + Assert.That(FileUtility.IsBaseDirectory(@"C:\HELLO\..\B\..\a", @"C:\b\..\a")); + Assert.That(FileUtility.IsBaseDirectory(@"C:\.\B\..\.\.\a", @"C:\.\.\.\.\.\.\.\a")); + + Assert.That(!FileUtility.IsBaseDirectory(@"C:\b", @"C:\a\b\hello")); + Assert.That(!FileUtility.IsBaseDirectory(@"C:\a\b\hello", @"C:\b")); + Assert.That(!FileUtility.IsBaseDirectory(@"C:\a\x\fwufhweoe", @"C:\a\x\fwuFHweoex\a\b\hello")); + Assert.That(FileUtility.IsBaseDirectory(@"C:\", @"C:\")); + Assert.That(FileUtility.IsBaseDirectory(@"C:\", @"C:\a\b\hello")); + Assert.That(!FileUtility.IsBaseDirectory(@"C:\", @"D:\a\b\hello")); } [Test] public void TestIsBaseDirectoryRelative() { - Assert.IsTrue(FileUtility.IsBaseDirectory(@".", @"a\b")); - Assert.IsTrue(FileUtility.IsBaseDirectory(@".", @"a")); - Assert.IsFalse(FileUtility.IsBaseDirectory(@".", @"c:\")); - Assert.IsFalse(FileUtility.IsBaseDirectory(@".", @"/")); + Assert.That(FileUtility.IsBaseDirectory(@".", @"a\b")); + Assert.That(FileUtility.IsBaseDirectory(@".", @"a")); + Assert.That(!FileUtility.IsBaseDirectory(@".", @"c:\")); + Assert.That(!FileUtility.IsBaseDirectory(@".", @"/")); } [Test] public void TestIsBaseDirectoryUnixStyle() { - Assert.IsTrue(FileUtility.IsBaseDirectory(@"/", @"/")); - Assert.IsTrue(FileUtility.IsBaseDirectory(@"/", @"/a")); - Assert.IsTrue(FileUtility.IsBaseDirectory(@"/", @"/a/subdir")); + Assert.That(FileUtility.IsBaseDirectory(@"/", @"/")); + Assert.That(FileUtility.IsBaseDirectory(@"/", @"/a")); + Assert.That(FileUtility.IsBaseDirectory(@"/", @"/a/subdir")); } [Test] public void TestIsBaseDirectoryUNC() { - Assert.IsTrue(FileUtility.IsBaseDirectory(@"\\server\share", @"\\server\share\dir\subdir")); - Assert.IsTrue(FileUtility.IsBaseDirectory(@"\\server\share", @"\\server\share\dir\subdir")); - Assert.IsFalse(FileUtility.IsBaseDirectory(@"\\server2\share", @"\\server\share\dir\subdir")); + Assert.That(FileUtility.IsBaseDirectory(@"\\server\share", @"\\server\share\dir\subdir")); + Assert.That(FileUtility.IsBaseDirectory(@"\\server\share", @"\\server\share\dir\subdir")); + Assert.That(!FileUtility.IsBaseDirectory(@"\\server2\share", @"\\server\share\dir\subdir")); } [Test] public void TestGetRelativePath() { - Assert.AreEqual(@"blub", FileUtility.GetRelativePath(@"C:\hello\.\..\a", @"C:\.\a\blub")); - Assert.AreEqual(@"..\a\blub", FileUtility.GetRelativePath(@"C:\.\.\.\.\hello", @"C:\.\blub\.\..\.\a\.\blub")); - Assert.AreEqual(@"..\a\blub", FileUtility.GetRelativePath(@"C:\.\.\.\.\hello\", @"C:\.\blub\.\..\.\a\.\blub")); - Assert.AreEqual(@".", FileUtility.GetRelativePath(@"C:\hello", @"C:\.\hello")); - Assert.AreEqual(@".", FileUtility.GetRelativePath(@"C:\", @"C:\")); - Assert.AreEqual(@"blub", FileUtility.GetRelativePath(@"C:\", @"C:\blub")); - Assert.AreEqual(@"D:\", FileUtility.GetRelativePath(@"C:\", @"D:\")); - Assert.AreEqual(@"D:\def", FileUtility.GetRelativePath(@"C:\abc", @"D:\def")); + Assert.That(FileUtility.GetRelativePath(@"C:\hello\.\..\a", @"C:\.\a\blub"), Is.EqualTo(@"blub")); + Assert.That(FileUtility.GetRelativePath(@"C:\.\.\.\.\hello", @"C:\.\blub\.\..\.\a\.\blub"), Is.EqualTo(@"..\a\blub")); + Assert.That(FileUtility.GetRelativePath(@"C:\.\.\.\.\hello\", @"C:\.\blub\.\..\.\a\.\blub"), Is.EqualTo(@"..\a\blub")); + Assert.That(FileUtility.GetRelativePath(@"C:\hello", @"C:\.\hello"), Is.EqualTo(@".")); + Assert.That(FileUtility.GetRelativePath(@"C:\", @"C:\"), Is.EqualTo(@".")); + Assert.That(FileUtility.GetRelativePath(@"C:\", @"C:\blub"), Is.EqualTo(@"blub")); + Assert.That(FileUtility.GetRelativePath(@"C:\", @"D:\"), Is.EqualTo(@"D:\")); + Assert.That(FileUtility.GetRelativePath(@"C:\abc", @"D:\def"), Is.EqualTo(@"D:\def")); // casing troubles - Assert.AreEqual(@"blub", FileUtility.GetRelativePath(@"C:\hello\.\..\A", @"C:\.\a\blub")); - Assert.AreEqual(@"..\a\blub", FileUtility.GetRelativePath(@"C:\.\.\.\.\HELlo", @"C:\.\blub\.\..\.\a\.\blub")); - Assert.AreEqual(@"..\a\blub", FileUtility.GetRelativePath(@"C:\.\.\.\.\heLLo\A\..", @"C:\.\blub\.\..\.\a\.\blub")); + Assert.That(FileUtility.GetRelativePath(@"C:\hello\.\..\A", @"C:\.\a\blub"), Is.EqualTo(@"blub")); + Assert.That(FileUtility.GetRelativePath(@"C:\.\.\.\.\HELlo", @"C:\.\blub\.\..\.\a\.\blub"), Is.EqualTo(@"..\a\blub")); + Assert.That(FileUtility.GetRelativePath(@"C:\.\.\.\.\heLLo\A\..", @"C:\.\blub\.\..\.\a\.\blub"), Is.EqualTo(@"..\a\blub")); } [Test] public void RelativeGetRelativePath() { // Relative path - Assert.AreEqual(@"a", FileUtility.GetRelativePath(@".", @"a")); - Assert.AreEqual(@"..", FileUtility.GetRelativePath(@"a", @".")); - Assert.AreEqual(@"..\b", FileUtility.GetRelativePath(@"a", @"b")); - Assert.AreEqual(@"..\..", FileUtility.GetRelativePath(@"a", @"..")); + Assert.That(FileUtility.GetRelativePath(@".", @"a"), Is.EqualTo(@"a")); + Assert.That(FileUtility.GetRelativePath(@"a", @"."), Is.EqualTo(@"..")); + Assert.That(FileUtility.GetRelativePath(@"a", @"b"), Is.EqualTo(@"..\b")); + Assert.That(FileUtility.GetRelativePath(@"a", @".."), Is.EqualTo(@"..\..")); // Getting a path from an absolute path to a relative path isn't really possible; // so we just keep the existing relative path (don't introduce incorrect '..\'). - Assert.AreEqual(@"def", FileUtility.GetRelativePath(@"C:\abc", @"def")); + Assert.That(FileUtility.GetRelativePath(@"C:\abc", @"def"), Is.EqualTo(@"def")); } [Test] public void GetRelativePath_Unix() { - Assert.AreEqual(@"a", FileUtility.GetRelativePath("/", "/a")); - Assert.AreEqual(@"a\b", FileUtility.GetRelativePath("/", "/a/b")); - Assert.AreEqual(@"b", FileUtility.GetRelativePath("/a", "/a/b")); + Assert.That(FileUtility.GetRelativePath("/", "/a"), Is.EqualTo(@"a")); + Assert.That(FileUtility.GetRelativePath("/", "/a/b"), Is.EqualTo(@"a\b")); + Assert.That(FileUtility.GetRelativePath("/a", "/a/b"), Is.EqualTo(@"b")); } [Test] public void TestIsEqualFile() { - Assert.IsTrue(FileUtility.IsEqualFileName(@"C:\.\Hello World.Exe", @"C:\HELLO WOrld.exe")); - Assert.IsTrue(FileUtility.IsEqualFileName(@"C:\bla\..\a\my.file.is.this", @"C:\gg\..\.\.\.\.\a\..\a\MY.FILE.IS.THIS")); + Assert.That(FileUtility.IsEqualFileName(@"C:\.\Hello World.Exe", @"C:\HELLO WOrld.exe")); + Assert.That(FileUtility.IsEqualFileName(@"C:\bla\..\a\my.file.is.this", @"C:\gg\..\.\.\.\.\a\..\a\MY.FILE.IS.THIS")); - Assert.IsFalse(FileUtility.IsEqualFileName(@"C:\.\Hello World.Exe", @"C:\HELLO_WOrld.exe")); - Assert.IsFalse(FileUtility.IsEqualFileName(@"C:\a\my.file.is.this", @"C:\gg\..\.\.\.\.\a\..\b\MY.FILE.IS.THIS")); + Assert.That(!FileUtility.IsEqualFileName(@"C:\.\Hello World.Exe", @"C:\HELLO_WOrld.exe")); + Assert.That(!FileUtility.IsEqualFileName(@"C:\a\my.file.is.this", @"C:\gg\..\.\.\.\.\a\..\b\MY.FILE.IS.THIS")); } } } \ No newline at end of file diff --git a/ICSharpCode.Decompiler.Tests/Util/IntervalTests.cs b/ICSharpCode.Decompiler.Tests/Util/IntervalTests.cs index 6fcf322af4..ff7dbcf1b5 100644 --- a/ICSharpCode.Decompiler.Tests/Util/IntervalTests.cs +++ b/ICSharpCode.Decompiler.Tests/Util/IntervalTests.cs @@ -27,54 +27,54 @@ public class IntervalTests [Test] public void DefaultIsEmpty() { - Assert.IsTrue(default(Interval).IsEmpty); - Assert.IsFalse(default(Interval).Contains(-1)); - Assert.IsFalse(default(Interval).Contains(0)); - Assert.IsFalse(default(Interval).Contains(1)); + Assert.That(default(Interval).IsEmpty); + Assert.That(!default(Interval).Contains(-1)); + Assert.That(!default(Interval).Contains(0)); + Assert.That(!default(Interval).Contains(1)); } [Test] public void EmptyAt1() { Interval i = new Interval(1, 1); - Assert.IsTrue(default(Interval).IsEmpty); - Assert.IsFalse(default(Interval).Contains(-1)); - Assert.IsFalse(default(Interval).Contains(0)); - Assert.IsFalse(default(Interval).Contains(1)); - Assert.IsFalse(default(Interval).Contains(2)); + Assert.That(default(Interval).IsEmpty); + Assert.That(!default(Interval).Contains(-1)); + Assert.That(!default(Interval).Contains(0)); + Assert.That(!default(Interval).Contains(1)); + Assert.That(!default(Interval).Contains(2)); } [Test] public void OneToThree() { Interval i = new Interval(1, 3); - Assert.IsFalse(i.IsEmpty); - Assert.IsFalse(i.Contains(0)); - Assert.IsTrue(i.Contains(1)); - Assert.IsTrue(i.Contains(2)); - Assert.IsFalse(i.Contains(3)); + Assert.That(!i.IsEmpty); + Assert.That(!i.Contains(0)); + Assert.That(i.Contains(1)); + Assert.That(i.Contains(2)); + Assert.That(!i.Contains(3)); } [Test] public void FullInterval() { Interval full = new Interval(int.MinValue, int.MinValue); - Assert.IsFalse(full.IsEmpty); - Assert.IsTrue(full.Contains(int.MinValue)); - Assert.IsTrue(full.Contains(0)); - Assert.IsTrue(full.Contains(int.MaxValue)); + Assert.That(!full.IsEmpty); + Assert.That(full.Contains(int.MinValue)); + Assert.That(full.Contains(0)); + Assert.That(full.Contains(int.MaxValue)); } [Test] public void NonNegativeIntegers() { Interval i = new Interval(0, int.MinValue); - Assert.IsFalse(i.IsEmpty); - Assert.IsTrue(i.Contains(0)); - Assert.IsTrue(i.Contains(1000)); - Assert.IsTrue(i.Contains(int.MaxValue)); - Assert.IsFalse(i.Contains(-1)); - Assert.IsFalse(i.Contains(-1000)); - Assert.IsFalse(i.Contains(int.MinValue)); + Assert.That(!i.IsEmpty); + Assert.That(i.Contains(0)); + Assert.That(i.Contains(1000)); + Assert.That(i.Contains(int.MaxValue)); + Assert.That(!i.Contains(-1)); + Assert.That(!i.Contains(-1000)); + Assert.That(!i.Contains(int.MinValue)); } [Test] @@ -87,12 +87,12 @@ public void Intersection() Interval nonneg = new Interval(0, int.MinValue); Interval nonpos = new Interval(int.MinValue, 1); Interval maxval = new Interval(int.MaxValue, int.MinValue); - Assert.AreEqual(nonneg, full.Intersect(nonneg)); - Assert.AreEqual(nonneg, nonneg.Intersect(full)); - Assert.AreEqual(zero, nonneg.Intersect(zero)); - Assert.AreEqual(zero, nonneg.Intersect(nonpos)); - Assert.AreEqual(maxval, nonneg.Intersect(maxval)); - Assert.AreEqual(empty, nonpos.Intersect(maxval)); + Assert.That(full.Intersect(nonneg), Is.EqualTo(nonneg)); + Assert.That(nonneg.Intersect(full), Is.EqualTo(nonneg)); + Assert.That(nonneg.Intersect(zero), Is.EqualTo(zero)); + Assert.That(nonneg.Intersect(nonpos), Is.EqualTo(zero)); + Assert.That(nonneg.Intersect(maxval), Is.EqualTo(maxval)); + Assert.That(nonpos.Intersect(maxval), Is.EqualTo(empty)); } } } diff --git a/ICSharpCode.Decompiler.Tests/Util/LongSetTests.cs b/ICSharpCode.Decompiler.Tests/Util/LongSetTests.cs index 1718a394bb..e74c8a6980 100644 --- a/ICSharpCode.Decompiler.Tests/Util/LongSetTests.cs +++ b/ICSharpCode.Decompiler.Tests/Util/LongSetTests.cs @@ -32,94 +32,92 @@ public class LongSetTests public void UpperBound() { var longSet = new LongSet(new[] { new LongInterval(1, 5), new LongInterval(6, 7) }.ToImmutableArray()); - Assert.AreEqual(0, longSet.upper_bound(0)); + Assert.That(longSet.upper_bound(0), Is.EqualTo(0)); for (int i = 1; i <= 5; i++) - Assert.AreEqual(1, longSet.upper_bound(i)); + Assert.That(longSet.upper_bound(i), Is.EqualTo(1)); for (int i = 6; i <= 10; i++) - Assert.AreEqual(2, longSet.upper_bound(i)); + Assert.That(longSet.upper_bound(i), Is.EqualTo(2)); } [Test] public void UniverseContainsAll() { - Assert.IsTrue(LongSet.Universe.Contains(long.MinValue)); - Assert.IsTrue(LongSet.Universe.Contains(1)); - Assert.IsTrue(LongSet.Universe.Contains(long.MaxValue)); - Assert.IsFalse(LongSet.Universe.IsEmpty); + Assert.That(LongSet.Universe.Contains(long.MinValue)); + Assert.That(LongSet.Universe.Contains(1)); + Assert.That(LongSet.Universe.Contains(long.MaxValue)); + Assert.That(!LongSet.Universe.IsEmpty); } [Test] public void IntersectUniverse() { - Assert.AreEqual(LongSet.Universe, LongSet.Universe.IntersectWith(LongSet.Universe)); - Assert.AreEqual(LongSet.Empty, LongSet.Universe.IntersectWith(LongSet.Empty)); - Assert.AreEqual(new LongSet(long.MaxValue), LongSet.Universe.IntersectWith(new LongSet(long.MaxValue))); + Assert.That(LongSet.Universe.IntersectWith(LongSet.Universe), Is.EqualTo(LongSet.Universe)); + Assert.That(LongSet.Universe.IntersectWith(LongSet.Empty), Is.EqualTo(LongSet.Empty)); + Assert.That(LongSet.Universe.IntersectWith(new LongSet(long.MaxValue)), Is.EqualTo(new LongSet(long.MaxValue))); var longSet = new LongSet(new[] { new LongInterval(1, 5), new LongInterval(6, 7) }.ToImmutableArray()); - Assert.AreEqual(longSet, longSet.IntersectWith(LongSet.Universe)); + Assert.That(longSet.IntersectWith(LongSet.Universe), Is.EqualTo(longSet)); } [Test] public void UnionUniverse() { - Assert.AreEqual(LongSet.Universe, LongSet.Universe.UnionWith(LongSet.Universe)); - Assert.AreEqual(LongSet.Universe, LongSet.Universe.UnionWith(LongSet.Empty)); - Assert.AreEqual(LongSet.Universe, LongSet.Universe.UnionWith(new LongSet(long.MaxValue))); + Assert.That(LongSet.Universe.UnionWith(LongSet.Universe), Is.EqualTo(LongSet.Universe)); + Assert.That(LongSet.Universe.UnionWith(LongSet.Empty), Is.EqualTo(LongSet.Universe)); + Assert.That(LongSet.Universe.UnionWith(new LongSet(long.MaxValue)), Is.EqualTo(LongSet.Universe)); var longSet = new LongSet(new[] { new LongInterval(1, 5), new LongInterval(6, 7) }.ToImmutableArray()); - Assert.AreEqual(LongSet.Universe, longSet.UnionWith(LongSet.Universe)); + Assert.That(longSet.UnionWith(LongSet.Universe), Is.EqualTo(LongSet.Universe)); } [Test] public void ExceptWithUniverse() { - Assert.AreEqual(LongSet.Universe, LongSet.Universe.ExceptWith(LongSet.Empty)); - Assert.AreEqual(LongSet.Empty, LongSet.Universe.ExceptWith(LongSet.Universe)); - Assert.AreEqual(LongSet.Empty, LongSet.Empty.ExceptWith(LongSet.Universe)); - Assert.AreEqual(LongSet.Empty, LongSet.Empty.ExceptWith(LongSet.Empty)); + Assert.That(LongSet.Universe.ExceptWith(LongSet.Empty), Is.EqualTo(LongSet.Universe)); + Assert.That(LongSet.Universe.ExceptWith(LongSet.Universe), Is.EqualTo(LongSet.Empty)); + Assert.That(LongSet.Empty.ExceptWith(LongSet.Universe), Is.EqualTo(LongSet.Empty)); + Assert.That(LongSet.Empty.ExceptWith(LongSet.Empty), Is.EqualTo(LongSet.Empty)); } [Test] public void UnionWith() { - Assert.AreEqual(new LongSet(new LongInterval(0, 2)), - new LongSet(0).UnionWith(new LongSet(1))); + Assert.That(new LongSet(0).UnionWith(new LongSet(1)), Is.EqualTo(new LongSet(new LongInterval(0, 2)))); - Assert.AreEqual(LongSet.Universe, new LongSet(0).Invert().UnionWith(new LongSet(0))); + Assert.That(new LongSet(0).Invert().UnionWith(new LongSet(0)), Is.EqualTo(LongSet.Universe)); } [Test] public void AddTo() { - Assert.AreEqual(new LongSet(1), new LongSet(0).AddOffset(1)); - Assert.AreEqual(new LongSet(long.MinValue), new LongSet(long.MaxValue).AddOffset(1)); + Assert.That(new LongSet(0).AddOffset(1), Is.EqualTo(new LongSet(1))); + Assert.That(new LongSet(long.MaxValue).AddOffset(1), Is.EqualTo(new LongSet(long.MinValue))); TestAddTo(new LongSet(new LongInterval(-10, 10)), 5); TestAddTo(new LongSet(new LongInterval(-10, 10)), long.MaxValue); - Assert.AreEqual(new LongSet(10).Invert(), new LongSet(0).Invert().AddOffset(10)); - Assert.AreEqual(new LongSet(20).Invert(), new LongSet(30).Invert().AddOffset(-10)); + Assert.That(new LongSet(0).Invert().AddOffset(10), Is.EqualTo(new LongSet(10).Invert())); + Assert.That(new LongSet(30).Invert().AddOffset(-10), Is.EqualTo(new LongSet(20).Invert())); } void TestAddTo(LongSet input, long constant) { - Assert.AreEqual( - input.Values.Select(e => unchecked(e + constant)).OrderBy(e => e).ToList(), - input.AddOffset(constant).Values.ToList()); + Assert.That( + input.AddOffset(constant).Values.ToList(), Is.EqualTo(input.Values.Select(e => unchecked(e + constant)).OrderBy(e => e).ToList())); } [Test] public void Values() { - Assert.IsFalse(LongSet.Empty.Values.Any()); - Assert.IsTrue(LongSet.Universe.Values.Any()); - Assert.AreEqual(new[] { 1, 2, 3 }, new LongSet(LongInterval.Inclusive(1, 3)).Values.ToArray()); + Assert.That(!LongSet.Empty.Values.Any()); + Assert.That(LongSet.Universe.Values.Any()); + Assert.That(new LongSet(LongInterval.Inclusive(1, 3)).Values.ToArray(), Is.EqualTo(new[] { 1, 2, 3 })); } [Test] public void ValueCount() { - Assert.AreEqual(0, LongSet.Empty.Count()); - Assert.AreEqual(ulong.MaxValue, new LongSet(3).Invert().Count()); - Assert.AreEqual(ulong.MaxValue, LongSet.Universe.Count()); - Assert.AreEqual(long.MaxValue + 2ul, new LongSet(LongInterval.Inclusive(-1, long.MaxValue)).Count()); + Assert.That(LongSet.Empty.Count(), Is.EqualTo(0)); + Assert.That(new LongSet(3).Invert().Count(), Is.EqualTo(ulong.MaxValue)); + Assert.That(LongSet.Universe.Count(), Is.EqualTo(ulong.MaxValue)); + Assert.That(new LongSet(LongInterval.Inclusive(-1, long.MaxValue)).Count(), Is.EqualTo(long.MaxValue + 2ul)); } } } diff --git a/ICSharpCode.Decompiler.Tests/Util/ResourceReaderWriterTests.cs b/ICSharpCode.Decompiler.Tests/Util/ResourceReaderWriterTests.cs index cad0afa930..59f8aadce0 100644 --- a/ICSharpCode.Decompiler.Tests/Util/ResourceReaderWriterTests.cs +++ b/ICSharpCode.Decompiler.Tests/Util/ResourceReaderWriterTests.cs @@ -100,9 +100,9 @@ public void Read(string name, object value) using var testFile = ProduceResourcesTestFile(name, value); using var reader = new ResourcesFile(testFile); var items = reader.ToArray(); - Assert.AreEqual(1, items.Length); - Assert.AreEqual(name, items[0].Key); - Assert.AreEqual(value, items[0].Value); + Assert.That(items.Length, Is.EqualTo(1)); + Assert.That(items[0].Key, Is.EqualTo(name)); + Assert.That(items[0].Value, Is.EqualTo(value)); } [TestCase("Null", null, null, "System.Resources.ResXNullRef" + WinFormsAssemblyName)] @@ -124,14 +124,14 @@ public void Read(string name, object value) public void Write(string name, object value, string serializedValue, string typeName) { var element = ProduceResXTest(name, value); - Assert.AreEqual(name, element.Attribute("name")?.Value); + Assert.That(element.Attribute("name")?.Value, Is.EqualTo(name)); if (typeName != null) { - Assert.AreEqual(typeName, element.Attribute("type")?.Value); + Assert.That(element.Attribute("type")?.Value, Is.EqualTo(typeName)); } var v = element.Element("value"); - Assert.IsNotNull(v); - Assert.IsTrue(v.IsEmpty ? serializedValue == null : v.Value == serializedValue); + Assert.That(v, Is.Not.Null); + Assert.That(v.IsEmpty ? serializedValue == null : v.Value == serializedValue); } [Test] @@ -149,10 +149,10 @@ public void BitmapIsResourceSerializedObject() .GetManifestResourceStream(typeof(ResourceReaderWriterTests).Namespace + ".Test.resources"); using var reader = new ResourcesFile(stream); var items = reader.ToArray(); - Assert.AreEqual(3, items.Length); + Assert.That(items.Length, Is.EqualTo(3)); var item = items.FirstOrDefault(i => i.Key == "Bitmap"); - Assert.IsNotNull(item.Key); - Assert.IsInstanceOf(item.Value); + Assert.That(item.Key, Is.Not.Null); + Assert.That(item.Value, Is.InstanceOf()); } [Test] @@ -162,15 +162,15 @@ public void ByteArrayIsSupported() .GetManifestResourceStream(typeof(ResourceReaderWriterTests).Namespace + ".Test.resources"); using var reader = new ResourcesFile(stream); var items = reader.ToArray(); - Assert.AreEqual(3, items.Length); + Assert.That(items.Length, Is.EqualTo(3)); var item = items.FirstOrDefault(i => i.Key == "Byte[]"); - Assert.IsNotNull(item.Key); - Assert.IsInstanceOf(item.Value); + Assert.That(item.Key, Is.Not.Null); + Assert.That(item.Value, Is.InstanceOf()); byte[] array = (byte[])item.Value; - Assert.AreEqual(3, array.Length); - Assert.AreEqual(42, array[0]); - Assert.AreEqual(43, array[1]); - Assert.AreEqual(44, array[2]); + Assert.That(array.Length, Is.EqualTo(3)); + Assert.That(array[0], Is.EqualTo(42)); + Assert.That(array[1], Is.EqualTo(43)); + Assert.That(array[2], Is.EqualTo(44)); } [Test] @@ -180,10 +180,10 @@ public void MemoryStreamIsSupported() .GetManifestResourceStream(typeof(ResourceReaderWriterTests).Namespace + ".Test.resources"); using var reader = new ResourcesFile(stream); var items = reader.ToArray(); - Assert.AreEqual(3, items.Length); + Assert.That(items.Length, Is.EqualTo(3)); var item = items.FirstOrDefault(i => i.Key == "MemoryStream"); - Assert.IsNotNull(item.Key); - Assert.IsInstanceOf(item.Value); + Assert.That(item.Key, Is.Not.Null); + Assert.That(item.Value, Is.InstanceOf()); } } } \ No newline at end of file diff --git a/ICSharpCode.Decompiler.Tests/VBPrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/VBPrettyTestRunner.cs index 2dcd061392..c21dc07758 100644 --- a/ICSharpCode.Decompiler.Tests/VBPrettyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/VBPrettyTestRunner.cs @@ -45,8 +45,8 @@ public void AllFilesHaveTests() if (file.Extension.Equals(".vb", StringComparison.OrdinalIgnoreCase)) { var testName = file.Name.Split('.')[0]; - Assert.Contains(testName, testNames); - Assert.IsTrue(File.Exists(Path.Combine(TestCasePath, testName + ".cs"))); + Assert.That(testNames, Has.Member(testName)); + Assert.That(File.Exists(Path.Combine(TestCasePath, testName + ".cs"))); } } } diff --git a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs index 81a2b328bc..cedf888944 100644 --- a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs +++ b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs @@ -1339,10 +1339,6 @@ EntityDeclaration DoDecompile(ITypeDefinition typeDef, DecompileRun decompileRun } } - decompileRun.EnumValueDisplayMode = typeDef.Kind == TypeKind.Enum - ? DetectBestEnumValueDisplayMode(typeDef, module.PEFile) - : null; - // With C# 9 records, the relative order of fields and properties matters: IEnumerable fieldsAndProperties = recordDecompiler?.FieldsAndProperties ?? typeDef.Fields.Concat(typeDef.Properties); @@ -1406,7 +1402,9 @@ EntityDeclaration DoDecompile(ITypeDefinition typeDef, DecompileRun decompileRun } if (typeDecl.ClassType == ClassType.Enum) { - switch (decompileRun.EnumValueDisplayMode) + Debug.Assert(typeDef.Kind == TypeKind.Enum); + EnumValueDisplayMode displayMode = DetectBestEnumValueDisplayMode(typeDef, module.PEFile); + switch (displayMode) { case EnumValueDisplayMode.FirstOnly: foreach (var enumMember in typeDecl.Members.OfType().Skip(1)) @@ -1425,13 +1423,33 @@ EntityDeclaration DoDecompile(ITypeDefinition typeDef, DecompileRun decompileRun } break; case EnumValueDisplayMode.All: - case EnumValueDisplayMode.AllHex: // nothing needs to be changed. break; + case EnumValueDisplayMode.AllHex: + foreach (var enumMember in typeDecl.Members.OfType()) + { + var constantValue = (enumMember.GetSymbol() as IField).GetConstantValue(); + if (constantValue == null || enumMember.Initializer is not PrimitiveExpression pe) + { + continue; + } + long initValue = (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, constantValue, false); + if (initValue >= 10) + { + pe.Format = LiteralFormat.HexadecimalNumber; + } + } + break; default: throw new ArgumentOutOfRangeException(); } - decompileRun.EnumValueDisplayMode = null; + foreach (var item in typeDecl.Members) + { + if (item is not EnumMemberDeclaration) + { + typeDecl.InsertChildBefore(item, new Comment(" error: nested types are not permitted in C#."), Roles.Comment); + } + } } return typeDecl; } @@ -1927,13 +1945,7 @@ EntityDeclaration DoDecompile(IField field, DecompileRun decompileRun, ITypeReso object constantValue = field.GetConstantValue(); if (constantValue != null) { - long initValue = (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, constantValue, false); enumDec.Initializer = typeSystemAstBuilder.ConvertConstantValue(decompilationContext.CurrentTypeDefinition.EnumUnderlyingType, constantValue); - if (enumDec.Initializer is PrimitiveExpression primitive - && initValue >= 10 && decompileRun.EnumValueDisplayMode == EnumValueDisplayMode.AllHex) - { - primitive.Format = LiteralFormat.HexadecimalNumber; - } } enumDec.Attributes.AddRange(field.GetAttributes().Select(a => new AttributeSection(typeSystemAstBuilder.ConvertAttribute(a)))); enumDec.AddAnnotation(new MemberResolveResult(null, field)); diff --git a/ICSharpCode.Decompiler/CSharp/CallBuilder.cs b/ICSharpCode.Decompiler/CSharp/CallBuilder.cs index d0f4c056c0..d34ec1cfd1 100644 --- a/ICSharpCode.Decompiler/CSharp/CallBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/CallBuilder.cs @@ -189,7 +189,7 @@ public CallBuilder(ExpressionBuilder expressionBuilder, IDecompilerTypeSystem ty this.typeSystem = typeSystem; } - public TranslatedExpression Build(CallInstruction inst) + public TranslatedExpression Build(CallInstruction inst, IType typeHint = null) { if (inst is NewObj newobj && IL.Transforms.DelegateConstruction.MatchDelegateConstruction(newobj, out _, out _, out _)) { @@ -198,20 +198,29 @@ public TranslatedExpression Build(CallInstruction inst) if (settings.TupleTypes && TupleTransform.MatchTupleConstruction(inst as NewObj, out var tupleElements) && tupleElements.Length >= 2) { var elementTypes = TupleType.GetTupleElementTypes(inst.Method.DeclaringType); - Debug.Assert(!elementTypes.IsDefault, "MatchTupleConstruction should not success unless we got a valid tuple type."); + var elementNames = typeHint is TupleType tt ? tt.ElementNames : default; + Debug.Assert(!elementTypes.IsDefault, "MatchTupleConstruction should not succeed unless we got a valid tuple type."); Debug.Assert(elementTypes.Length == tupleElements.Length); var tuple = new TupleExpression(); var elementRRs = new List(); - foreach (var (element, elementType) in tupleElements.Zip(elementTypes)) + foreach (var (index, element, elementType) in tupleElements.ZipWithIndex(elementTypes)) { var translatedElement = expressionBuilder.Translate(element, elementType) .ConvertTo(elementType, expressionBuilder, allowImplicitConversion: true); - tuple.Elements.Add(translatedElement.Expression); + if (elementNames.IsDefaultOrEmpty || elementNames.ElementAtOrDefault(index) is not string { Length: > 0 } name) + { + tuple.Elements.Add(translatedElement.Expression); + } + else + { + tuple.Elements.Add(new NamedArgumentExpression(name, translatedElement.Expression)); + } elementRRs.Add(translatedElement.ResolveResult); } return tuple.WithRR(new TupleResolveResult( expressionBuilder.compilation, elementRRs.ToImmutableArray(), + elementNames, valueTupleAssembly: inst.Method.DeclaringType.GetDefinition()?.ParentModule )).WithILInstruction(inst); } diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index d0cdde6def..0a3dddb155 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -22,7 +22,6 @@ using System.Diagnostics; using System.Linq; using System.Reflection.Metadata; -using System.Runtime.CompilerServices; using System.Threading; using ICSharpCode.Decompiler.CSharp.Resolver; @@ -438,7 +437,7 @@ protected internal override TranslatedExpression VisitNewObj(NewObj inst, Transl return TranslateStackAllocInitializer(b, type.TypeArguments[0]); } } - return new CallBuilder(this, typeSystem, settings).Build(inst); + return new CallBuilder(this, typeSystem, settings).Build(inst, context.TypeHint); } protected internal override TranslatedExpression VisitLdVirtDelegate(LdVirtDelegate inst, TranslationContext context) diff --git a/ICSharpCode.Decompiler/CSharp/Resolver/CSharpResolver.cs b/ICSharpCode.Decompiler/CSharp/Resolver/CSharpResolver.cs index f235e0a98a..14ab787ba0 100644 --- a/ICSharpCode.Decompiler/CSharp/Resolver/CSharpResolver.cs +++ b/ICSharpCode.Decompiler/CSharp/Resolver/CSharpResolver.cs @@ -67,7 +67,7 @@ public CSharpResolver(CSharpTypeResolveContext context) currentTypeDefinitionCache = new TypeDefinitionCache(context.CurrentTypeDefinition); } - private CSharpResolver(ICompilation compilation, CSharpConversions conversions, CSharpTypeResolveContext context, bool checkForOverflow, bool isWithinLambdaExpression, TypeDefinitionCache currentTypeDefinitionCache, ImmutableStack localVariableStack, ObjectInitializerContext objectInitializerStack) + private CSharpResolver(ICompilation compilation, CSharpConversions conversions, CSharpTypeResolveContext context, bool checkForOverflow, bool isWithinLambdaExpression, TypeDefinitionCache currentTypeDefinitionCache, ImmutableStack> localVariableStack, ObjectInitializerContext objectInitializerStack) { this.compilation = compilation; this.conversions = conversions; @@ -228,54 +228,21 @@ public TypeDefinitionCache(ITypeDefinition typeDefinition) // The beginning of a block is marked by a null entry. // This data structure is used to allow efficient cloning of the resolver with its local variable context. - readonly ImmutableStack localVariableStack = ImmutableStack.Empty; + readonly ImmutableStack> localVariableStack = ImmutableStack>.Empty; - CSharpResolver WithLocalVariableStack(ImmutableStack stack) + CSharpResolver WithLocalVariableStack(ImmutableStack> stack) { return new CSharpResolver(compilation, conversions, context, checkForOverflow, isWithinLambdaExpression, currentTypeDefinitionCache, stack, objectInitializerStack); } /// - /// Opens a new scope for local variables. + /// Adds new variableŝ or lambda parameters to the current block. /// - public CSharpResolver PushBlock() + public CSharpResolver AddVariables(Dictionary variables) { - return WithLocalVariableStack(localVariableStack.Push(null)); - } - - /// - /// Closes the current scope for local variables; removing all variables in that scope. - /// - public CSharpResolver PopBlock() - { - var stack = localVariableStack; - IVariable removedVar; - do - { - removedVar = stack.Peek(); - stack = stack.Pop(); - } while (removedVar != null); - return WithLocalVariableStack(stack); - } - - /// - /// Adds a new variable or lambda parameter to the current block. - /// - public CSharpResolver AddVariable(IVariable variable) - { - if (variable == null) - throw new ArgumentNullException(nameof(variable)); - return WithLocalVariableStack(localVariableStack.Push(variable)); - } - - /// - /// Removes the variable that was just added. - /// - public CSharpResolver PopLastVariable() - { - if (localVariableStack.Peek() == null) - throw new InvalidOperationException("There is no variable within the current block."); - return WithLocalVariableStack(localVariableStack.Pop()); + if (variables == null) + throw new ArgumentNullException(nameof(variables)); + return WithLocalVariableStack(localVariableStack.Push(variables)); } /// @@ -284,7 +251,7 @@ public CSharpResolver PopLastVariable() /// public IEnumerable LocalVariables { get { - return localVariableStack.Where(v => v != null); + return localVariableStack.SelectMany(s => s.Values); } } #endregion @@ -1515,9 +1482,9 @@ public ResolveResult LookupSimpleNameOrTypeName(string identifier, IReadOnlyList if (lookupMode == NameLookupMode.Expression || lookupMode == NameLookupMode.InvocationTarget) { // Look in local variables - foreach (IVariable v in this.LocalVariables) + foreach (Dictionary variables in localVariableStack) { - if (v.Name == identifier) + if (variables.TryGetValue(identifier, out var v)) { return new LocalResolveResult(v); } diff --git a/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs b/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs index 61471cb35e..28bccd9526 100644 --- a/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs @@ -395,8 +395,14 @@ protected internal override TranslatedStatement VisitLeave(Leave inst) return new YieldBreakStatement().WithILInstruction(inst); else if (!inst.Value.MatchNop()) { + bool isLambdaOrExprTree = currentFunction.Kind is ILFunctionKind.ExpressionTree or ILFunctionKind.Delegate; var expr = exprBuilder.Translate(inst.Value, typeHint: currentResultType) .ConvertTo(currentResultType, exprBuilder, allowImplicitConversion: true); + if (isLambdaOrExprTree && IsPossibleLossOfTypeInformation(expr.Type, currentResultType)) + { + expr = new CastExpression(exprBuilder.ConvertType(currentResultType), expr) + .WithRR(new ConversionResolveResult(currentResultType, expr.ResolveResult, Conversion.IdentityConversion)).WithoutILInstruction(); + } return new ReturnStatement(expr).WithILInstruction(inst); } else @@ -419,6 +425,19 @@ protected internal override TranslatedStatement VisitLeave(Leave inst) return new GotoStatement(label).WithILInstruction(inst); } + private bool IsPossibleLossOfTypeInformation(IType givenType, IType expectedType) + { + if (NormalizeTypeVisitor.IgnoreNullability.EquivalentTypes(givenType, expectedType)) + return false; + if (expectedType is TupleType { ElementNames.IsEmpty: false }) + return true; + if (expectedType == SpecialType.Dynamic) + return true; + if (givenType == SpecialType.NullType) + return true; + return false; + } + protected internal override TranslatedStatement VisitThrow(Throw inst) { return new ThrowStatement(exprBuilder.Translate(inst.Argument)).WithILInstruction(inst); diff --git a/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUsingDeclarations.cs b/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUsingDeclarations.cs index a5a11344db..f8810e527d 100644 --- a/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUsingDeclarations.cs +++ b/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUsingDeclarations.cs @@ -161,11 +161,13 @@ TypeSystemAstBuilder CreateAstBuilder(CSharpTypeResolveContext context, IL.ILFun CSharpResolver resolver = new CSharpResolver(context); if (function != null) { + var variables = new Dictionary(); foreach (var v in function.Variables) { - if (v.Kind != IL.VariableKind.Parameter && v.Name != null) - resolver = resolver.AddVariable(new DefaultVariable(v.Type, v.Name)); + if (v.Kind != IL.VariableKind.Parameter && v.Name != null && !variables.ContainsKey(v.Name)) + variables.Add(v.Name, new DefaultVariable(v.Type, v.Name)); } + resolver = resolver.AddVariables(variables); } return new TypeSystemAstBuilder(resolver) { diff --git a/ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs b/ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs index 1350d21d3b..ad864b5acd 100644 --- a/ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs +++ b/ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs @@ -272,11 +272,20 @@ public TranslatedExpression ConvertTo(IType targetType, ExpressionBuilder expres // Conversion of a tuple literal: convert element-wise var newTupleExpr = new TupleExpression(); var newElementRRs = new List(); - foreach (var (elementExpr, elementTargetType) in tupleExpr.Elements.Zip(targetTupleType.ElementTypes)) + // element names: discard existing names and use targetTupleType instead + var newElementNames = targetTupleType.ElementNames; + foreach (var (index, elementExpr, elementTargetType) in tupleExpr.Elements.ZipWithIndex(targetTupleType.ElementTypes)) { - var newElementExpr = new TranslatedExpression(elementExpr.Detach()) + var newElementExpr = new TranslatedExpression((elementExpr is NamedArgumentExpression nae ? nae.Expression : elementExpr).Detach()) .ConvertTo(elementTargetType, expressionBuilder, checkForOverflow, allowImplicitConversion); - newTupleExpr.Elements.Add(newElementExpr.Expression); + if (newElementNames.IsDefaultOrEmpty || newElementNames.ElementAtOrDefault(index) is not string { Length: > 0 } name) + { + newTupleExpr.Elements.Add(newElementExpr.Expression); + } + else + { + newTupleExpr.Elements.Add(new NamedArgumentExpression(name, newElementExpr.Expression)); + } newElementRRs.Add(newElementExpr.ResolveResult); } return newTupleExpr.WithILInstruction(this.ILInstructions) diff --git a/ICSharpCode.Decompiler/DebugInfo/IDebugInfoProvider.cs b/ICSharpCode.Decompiler/DebugInfo/IDebugInfoProvider.cs index 5c148df258..810919e567 100644 --- a/ICSharpCode.Decompiler/DebugInfo/IDebugInfoProvider.cs +++ b/ICSharpCode.Decompiler/DebugInfo/IDebugInfoProvider.cs @@ -17,12 +17,19 @@ public Variable(int index, string name) public string Name { get; } } + public struct PdbExtraTypeInfo + { + public string[] TupleElementNames; + public bool[] DynamicFlags; + } + public interface IDebugInfoProvider { string Description { get; } IList GetSequencePoints(MethodDefinitionHandle method); IList GetVariables(MethodDefinitionHandle method); bool TryGetName(MethodDefinitionHandle method, int index, out string name); + bool TryGetExtraTypeInfo(MethodDefinitionHandle method, int index, out PdbExtraTypeInfo extraTypeInfo); string SourceFileName { get; } } } diff --git a/ICSharpCode.Decompiler/DecompileRun.cs b/ICSharpCode.Decompiler/DecompileRun.cs index 2692ddf1af..8a1a31a90b 100644 --- a/ICSharpCode.Decompiler/DecompileRun.cs +++ b/ICSharpCode.Decompiler/DecompileRun.cs @@ -1,6 +1,23 @@ -using System; +// Copyright (c) 2018 Siegfried Pammer +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; using System.Collections.Generic; -using System.Text; using System.Threading; using ICSharpCode.Decompiler.CSharp; @@ -49,8 +66,6 @@ CSharp.TypeSystem.UsingScope CreateUsingScope(HashSet requiredNamespaces } return usingScope; } - - public EnumValueDisplayMode? EnumValueDisplayMode { get; set; } } enum EnumValueDisplayMode diff --git a/ICSharpCode.Decompiler/FlowAnalysis/ControlFlowNode.cs b/ICSharpCode.Decompiler/FlowAnalysis/ControlFlowNode.cs index 91c7f364dd..bb1365de0f 100644 --- a/ICSharpCode.Decompiler/FlowAnalysis/ControlFlowNode.cs +++ b/ICSharpCode.Decompiler/FlowAnalysis/ControlFlowNode.cs @@ -88,24 +88,32 @@ public void AddEdgeTo(ControlFlowNode target) public void TraversePreOrder(Func> children, Action visitAction) { - if (Visited) - return; - Visited = true; - visitAction(this); - foreach (ControlFlowNode t in children(this)) - t.TraversePreOrder(children, visitAction); + GraphTraversal.DepthFirstSearch(new[] { this }, Visit, children); + + bool Visit(ControlFlowNode node) + { + if (node.Visited) + return false; + node.Visited = true; + visitAction(node); + return true; + } } public void TraversePostOrder(Func> children, Action visitAction) { - if (Visited) - return; - Visited = true; - foreach (ControlFlowNode t in children(this)) - t.TraversePostOrder(children, visitAction); - visitAction(this); + GraphTraversal.DepthFirstSearch(new[] { this }, Visit, children, postorderAction: visitAction); + + bool Visit(ControlFlowNode node) + { + if (node.Visited) + return false; + node.Visited = true; + return true; + } } + /// /// Gets whether this dominates . /// diff --git a/ICSharpCode.Decompiler/FlowAnalysis/ReachingDefinitionsVisitor.cs b/ICSharpCode.Decompiler/FlowAnalysis/ReachingDefinitionsVisitor.cs index ff32e3f86c..0f57fab078 100644 --- a/ICSharpCode.Decompiler/FlowAnalysis/ReachingDefinitionsVisitor.cs +++ b/ICSharpCode.Decompiler/FlowAnalysis/ReachingDefinitionsVisitor.cs @@ -185,6 +185,11 @@ public bool IsReachingStore(int storeIndex) return bits[storeIndex]; } + public int NextReachingStore(int startIndex, int endIndex) + { + return bits.NextSetBit(startIndex, endIndex); + } + public void SetStore(int storeIndex) { Debug.Assert(storeIndex >= FirstStoreIndex); @@ -421,14 +426,18 @@ public bool IsAnalyzedVariable(ILVariable v) protected IEnumerable GetStores(State state, ILVariable v) { Debug.Assert(v.Function == scope && analyzedVariables[v.IndexInFunction]); + int startIndex = firstStoreIndexForVariable[v.IndexInFunction] + 1; int endIndex = firstStoreIndexForVariable[v.IndexInFunction + 1]; - for (int si = firstStoreIndexForVariable[v.IndexInFunction] + 1; si < endIndex; si++) + while (startIndex < endIndex) { - if (state.IsReachingStore(si)) + int nextReachingStore = state.NextReachingStore(startIndex, endIndex); + if (nextReachingStore == -1) { - Debug.Assert(((IInstructionWithVariableOperand)allStores[si]).Variable == v); - yield return allStores[si]; + break; } + Debug.Assert(((IInstructionWithVariableOperand)allStores[nextReachingStore]).Variable == v); + yield return allStores[nextReachingStore]; + startIndex = nextReachingStore + 1; } } diff --git a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj index 3f8c724926..87ee648aa8 100644 --- a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj +++ b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj @@ -69,12 +69,14 @@ - + + false + - + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -84,7 +86,7 @@ - + @@ -95,6 +97,7 @@ + @@ -140,6 +143,7 @@ + @@ -657,6 +661,7 @@ + diff --git a/ICSharpCode.Decompiler/IL/ApplyPdbLocalTypeInfoTypeVisitor.cs b/ICSharpCode.Decompiler/IL/ApplyPdbLocalTypeInfoTypeVisitor.cs new file mode 100644 index 0000000000..1d8796c1e7 --- /dev/null +++ b/ICSharpCode.Decompiler/IL/ApplyPdbLocalTypeInfoTypeVisitor.cs @@ -0,0 +1,159 @@ +using System; +using System.Collections.Immutable; + +using ICSharpCode.Decompiler.DebugInfo; +using ICSharpCode.Decompiler.TypeSystem; +using ICSharpCode.Decompiler.TypeSystem.Implementation; + +namespace ICSharpCode.Decompiler.IL +{ + /// + /// Heavily based on + /// + sealed class ApplyPdbLocalTypeInfoTypeVisitor : TypeVisitor + { + private readonly bool[] dynamicData; + private readonly string[] tupleElementNames; + private int dynamicTypeIndex = 0; + private int tupleTypeIndex = 0; + + private ApplyPdbLocalTypeInfoTypeVisitor(bool[] dynamicData, string[] tupleElementNames) + { + this.dynamicData = dynamicData; + this.tupleElementNames = tupleElementNames; + } + + public static IType Apply(IType type, PdbExtraTypeInfo pdbExtraTypeInfo) + { + if (pdbExtraTypeInfo.DynamicFlags is null && pdbExtraTypeInfo.TupleElementNames is null) + return type; + return type.AcceptVisitor(new ApplyPdbLocalTypeInfoTypeVisitor(pdbExtraTypeInfo.DynamicFlags, pdbExtraTypeInfo.TupleElementNames)); + } + + public override IType VisitModOpt(ModifiedType type) + { + dynamicTypeIndex++; + return base.VisitModOpt(type); + } + + public override IType VisitModReq(ModifiedType type) + { + dynamicTypeIndex++; + return base.VisitModReq(type); + } + + public override IType VisitPointerType(PointerType type) + { + dynamicTypeIndex++; + return base.VisitPointerType(type); + } + + public override IType VisitArrayType(ArrayType type) + { + dynamicTypeIndex++; + return base.VisitArrayType(type); + } + + public override IType VisitByReferenceType(ByReferenceType type) + { + dynamicTypeIndex++; + return base.VisitByReferenceType(type); + } + + public override IType VisitTupleType(TupleType type) + { + if (tupleElementNames != null && tupleTypeIndex < tupleElementNames.Length) + { + int tupleCardinality = type.Cardinality; + string[] extractedValues = new string[tupleCardinality]; + Array.Copy(tupleElementNames, tupleTypeIndex, extractedValues, 0, + Math.Min(tupleCardinality, tupleElementNames.Length - tupleTypeIndex)); + var elementNames = ImmutableArray.CreateRange(extractedValues); + tupleTypeIndex += tupleCardinality; + + int level = 0; + var elementTypes = new IType[type.ElementTypes.Length]; + for (int i = 0; i < type.ElementTypes.Length; i++) + { + dynamicTypeIndex++; + IType elementType = type.ElementTypes[i]; + if (i != 0 && (i - level) % TupleType.RestPosition == 0 && elementType is TupleType tuple) + { + tupleTypeIndex += tuple.Cardinality; + level++; + } + elementTypes[i] = elementType.AcceptVisitor(this); + } + + return new TupleType( + type.Compilation, + elementTypes.ToImmutableArray(), + elementNames, + type.GetDefinition()?.ParentModule + ); + } + return base.VisitTupleType(type); + } + + public override IType VisitParameterizedType(ParameterizedType type) + { + if (TupleType.IsTupleCompatible(type, out var tupleCardinality)) + tupleTypeIndex += tupleCardinality; + // Visit generic type and type arguments. + // Like base implementation, except that it increments dynamicTypeIndex. + var genericType = type.GenericType.AcceptVisitor(this); + bool changed = type.GenericType != genericType; + var arguments = new IType[type.TypeArguments.Count]; + for (int i = 0; i < type.TypeArguments.Count; i++) + { + dynamicTypeIndex++; + arguments[i] = type.TypeArguments[i].AcceptVisitor(this); + changed = changed || arguments[i] != type.TypeArguments[i]; + } + if (!changed) + return type; + return new ParameterizedType(genericType, arguments); + } + + public override IType VisitFunctionPointerType(FunctionPointerType type) + { + dynamicTypeIndex++; + if (type.ReturnIsRefReadOnly) + { + dynamicTypeIndex++; + } + var returnType = type.ReturnType.AcceptVisitor(this); + bool changed = type.ReturnType != returnType; + var parameters = new IType[type.ParameterTypes.Length]; + for (int i = 0; i < parameters.Length; i++) + { + dynamicTypeIndex += type.ParameterReferenceKinds[i] switch { + ReferenceKind.None => 1, + ReferenceKind.Ref => 1, + ReferenceKind.Out => 2, // in/out also count the modreq + ReferenceKind.In => 2, + _ => throw new NotSupportedException() + }; + parameters[i] = type.ParameterTypes[i].AcceptVisitor(this); + changed = changed || parameters[i] != type.ParameterTypes[i]; + } + if (!changed) + return type; + return type.WithSignature(returnType, parameters.ToImmutableArray()); + } + + public override IType VisitTypeDefinition(ITypeDefinition type) + { + IType newType = type; + var ktc = type.KnownTypeCode; + if (ktc == KnownTypeCode.Object && dynamicData is not null) + { + if (dynamicTypeIndex >= dynamicData.Length) + newType = SpecialType.Dynamic; + else if (dynamicData[dynamicTypeIndex]) + newType = SpecialType.Dynamic; + } + return newType; + } + } +} diff --git a/ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs b/ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs index 474e3031dc..bc6e103444 100644 --- a/ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs +++ b/ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs @@ -93,6 +93,7 @@ private void HandleIfInstruction(Block block, IfInstruction ifInst) } PickBetterBlockExit(block, ifInst); OrderIfBlocks(ifInst); + context.IndexOfFirstAlreadyTransformedInstruction = block.Instructions.Count; } /// @@ -150,6 +151,7 @@ private bool InlineExitBranch(Block block) // The targetBlock was already processed, and is ready to embed var targetBlock = ((Branch)exitInst).TargetBlock; block.Instructions.RemoveAt(block.Instructions.Count - 1); + context.IndexOfFirstAlreadyTransformedInstruction = block.Instructions.Count; block.Instructions.AddRange(targetBlock.Instructions); targetBlock.Remove(); @@ -228,7 +230,9 @@ private void MergeCommonBranches(Block block, IfInstruction ifInst) { context.Step("Embed else-block for goto removal", ifInst); Debug.Assert(IsEmpty(ifInst.FalseInst)); - ifInst.FalseInst = ExtractBlock(block, block.Instructions.IndexOf(ifInst) + 1, block.Instructions.Count - 1); + Block newBlock = new Block(); + ifInst.FalseInst = newBlock; + ExtractBlock(block, block.Instructions.IndexOf(ifInst) + 1, block.Instructions.Count - 1, newBlock); } // if (...) { ...; goto blockExit; } blockExit; @@ -373,6 +377,7 @@ internal static void InvertIf(Block block, IfInstruction ifInst, ILTransformCont //save a copy var thenInst = ifInst.TrueInst; + thenInst.AddRef(); if (ifInst != block.Instructions.SecondToLastOrDefault()) { @@ -380,12 +385,14 @@ internal static void InvertIf(Block block, IfInstruction ifInst, ILTransformCont // Note that this will only extract instructions that were previously inlined from another block // (via InlineExitBranch), so the instructions are already fully-transformed. // So it's OK to move them into a nested block again (which hides them from the following block transforms). - ifInst.TrueInst = ExtractBlock(block, block.Instructions.IndexOf(ifInst) + 1, block.Instructions.Count); + var newBlock = new Block(); + ifInst.TrueInst = newBlock; + ExtractBlock(block, block.Instructions.IndexOf(ifInst) + 1, block.Instructions.Count, newBlock); } else { - block.Instructions.RemoveAt(block.Instructions.Count - 1); ifInst.TrueInst = exitInst; + block.Instructions.RemoveAt(block.Instructions.Count - 1); } if (thenInst is Block thenBlock) @@ -396,6 +403,7 @@ internal static void InvertIf(Block block, IfInstruction ifInst, ILTransformCont { block.Instructions.Add(thenInst); } + thenInst.ReleaseRef(); ifInst.Condition = Comp.LogicNot(ifInst.Condition); ExpressionTransforms.RunOnSingleStatement(ifInst, context); @@ -660,9 +668,8 @@ private static bool IsContinueBlock(BlockContainer container, Block block) /// /// Removes a subrange of instructions from a block and returns them in a new Block /// - internal static Block ExtractBlock(Block block, int startIndex, int endIndex) + internal static void ExtractBlock(Block block, int startIndex, int endIndex, Block extractedBlock) { - var extractedBlock = new Block(); for (int i = startIndex; i < endIndex; i++) { var inst = block.Instructions[i]; @@ -670,8 +677,6 @@ internal static Block ExtractBlock(Block block, int startIndex, int endIndex) extractedBlock.AddILRange(inst); } block.Instructions.RemoveRange(startIndex, endIndex - startIndex); - - return extractedBlock; } } } diff --git a/ICSharpCode.Decompiler/IL/ILReader.cs b/ICSharpCode.Decompiler/IL/ILReader.cs index 5aa7edb742..4aaa4a739e 100644 --- a/ICSharpCode.Decompiler/IL/ILReader.cs +++ b/ICSharpCode.Decompiler/IL/ILReader.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2014 Daniel Grunwald +// Copyright (c) 2014 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -304,6 +304,13 @@ ILVariable CreateILVariable(int index, IType type) { kind = VariableKind.Local; } + + if (UseDebugSymbols && DebugInfo is not null && + DebugInfo.TryGetExtraTypeInfo((MethodDefinitionHandle)method.MetadataToken, index, out var pdbExtraTypeInfo)) + { + type = ApplyPdbLocalTypeInfoTypeVisitor.Apply(type, pdbExtraTypeInfo); + } + ILVariable ilVar = new ILVariable(kind, type, index); if (!UseDebugSymbols || DebugInfo == null || !DebugInfo.TryGetName((MethodDefinitionHandle)method.MetadataToken, index, out string name)) { diff --git a/ICSharpCode.Decompiler/IL/ILVariable.cs b/ICSharpCode.Decompiler/IL/ILVariable.cs index 5f2610449c..e3ed60fa7d 100644 --- a/ICSharpCode.Decompiler/IL/ILVariable.cs +++ b/ICSharpCode.Decompiler/IL/ILVariable.cs @@ -652,9 +652,13 @@ public bool Equals(ILVariable? x, ILVariable? y) public int GetHashCode(ILVariable obj) { - if (obj.Kind == VariableKind.StackSlot) + if (obj.Kind is VariableKind.StackSlot or VariableKind.PatternLocal) return obj.GetHashCode(); - return (obj.Function, obj.Kind, obj.Index).GetHashCode(); + if (obj.Index != null) + return (obj.Function, obj.Kind, obj.Index).GetHashCode(); + if (obj.StateMachineField != null) + return (obj.Function, obj.Kind, obj.StateMachineField).GetHashCode(); + return obj.GetHashCode(); } } } diff --git a/ICSharpCode.Decompiler/IL/Instructions/Block.cs b/ICSharpCode.Decompiler/IL/Instructions/Block.cs index e8c486dbac..479a8f2079 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/Block.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/Block.cs @@ -328,6 +328,7 @@ public void RunTransforms(IEnumerable transforms, BlockTransfor foreach (var transform in transforms) { context.CancellationToken.ThrowIfCancellationRequested(); + Debug.Assert(context.IndexOfFirstAlreadyTransformedInstruction <= this.Instructions.Count); context.StepStartGroup(transform.GetType().Name); transform.Run(this, context); this.CheckInvariant(ILPhase.Normal); diff --git a/ICSharpCode.Decompiler/IL/Instructions/BlockContainer.cs b/ICSharpCode.Decompiler/IL/Instructions/BlockContainer.cs index 79b79d70ca..e4b8ecbefb 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/BlockContainer.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/BlockContainer.cs @@ -279,7 +279,7 @@ public List TopologicalSort(bool deleteUnreachableBlocks = false) // Visit blocks in post-order BitSet visited = new BitSet(Blocks.Count); List postOrder = new List(); - Visit(EntryPoint); + GraphTraversal.DepthFirstSearch(new[] { EntryPoint }, MarkAsVisited, Successors, postOrder.Add, reverseSuccessors: true); postOrder.Reverse(); if (!deleteUnreachableBlocks) { @@ -291,24 +291,30 @@ public List TopologicalSort(bool deleteUnreachableBlocks = false) } return postOrder; - void Visit(Block block) + bool MarkAsVisited(Block block) { Debug.Assert(block.Parent == this); if (!visited[block.ChildIndex]) { visited[block.ChildIndex] = true; + return true; + } + else + { + return false; + } + } - foreach (var branch in block.Descendants.OfType()) + IEnumerable Successors(Block block) + { + foreach (var branch in block.Descendants.OfType()) + { + if (branch.TargetBlock.Parent == this) { - if (branch.TargetBlock.Parent == this) - { - Visit(branch.TargetBlock); - } + yield return branch.TargetBlock; } - - postOrder.Add(block); } - }; + } } /// diff --git a/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs b/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs index 2832e9e25a..d84091d9d2 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs @@ -240,9 +240,13 @@ void AssignName() } else { - // use the name from the debug symbols - // (but ensure we don't use the same name for two variables) - v.Name = GetAlternativeName(v.Name); + // use the name from the debug symbols and update index appended to duplicates + string nameWithoutNumber = SplitName(v.Name, out int newIndex); + if (!reservedVariableNames.TryGetValue(nameWithoutNumber, out int currentIndex)) + { + currentIndex = 1; + } + reservedVariableNames[nameWithoutNumber] = Math.Max(newIndex, currentIndex); } } } @@ -274,7 +278,21 @@ void AssignName() var newName = localFunction.Name; if (newName == null) { - newName = GetAlternativeName("f"); + string nameWithoutNumber = "f"; + if (!reservedVariableNames.TryGetValue(nameWithoutNumber, out int currentIndex)) + { + currentIndex = 1; + } + int count = Math.Max(1, currentIndex) + 1; + reservedVariableNames[nameWithoutNumber] = count; + if (count > 1) + { + newName = nameWithoutNumber + count.ToString(); + } + else + { + newName = nameWithoutNumber; + } } localFunction.Name = newName; localFunction.ReducedMethod.Name = newName; @@ -342,42 +360,6 @@ internal static bool IsValidName(string varName) return true; } - public string GetAlternativeName(string oldVariableName) - { - if (oldVariableName.Length == 1 && oldVariableName[0] >= 'i' && oldVariableName[0] <= maxLoopVariableName) - { - for (char c = 'i'; c <= maxLoopVariableName; c++) - { - if (!reservedVariableNames.ContainsKey(c.ToString())) - { - reservedVariableNames.Add(c.ToString(), 1); - return c.ToString(); - } - } - } - - string nameWithoutDigits = SplitName(oldVariableName, out int number); - - if (!reservedVariableNames.ContainsKey(nameWithoutDigits)) - { - reservedVariableNames.Add(nameWithoutDigits, number - 1); - } - int count = ++reservedVariableNames[nameWithoutDigits]; - string nameWithDigits = nameWithoutDigits + count.ToString(); - if (oldVariableName == nameWithDigits) - { - return oldVariableName; - } - if (count != 1) - { - return nameWithDigits; - } - else - { - return nameWithoutDigits; - } - } - HashSet CollectLoopCounters(ILFunction function) { var loopCounters = new HashSet(); diff --git a/ICSharpCode.Decompiler/IL/Transforms/BlockTransform.cs b/ICSharpCode.Decompiler/IL/Transforms/BlockTransform.cs index ef1370f072..9ab6740feb 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/BlockTransform.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/BlockTransform.cs @@ -5,6 +5,7 @@ using ICSharpCode.Decompiler.FlowAnalysis; using ICSharpCode.Decompiler.IL.ControlFlow; +using ICSharpCode.Decompiler.Util; namespace ICSharpCode.Decompiler.IL.Transforms { @@ -53,6 +54,15 @@ public class BlockTransformContext : ILTransformContext /// public ControlFlowGraph ControlFlowGraph { get; set; } + /// + /// Initially equal to Block.Instructions.Count indicating that nothing has been transformed yet. + /// Set by when another already transformed block is merged into + /// the current block. Subsequent s must update this value, for example, + /// by resetting it to Block.Instructions.Count. will use this value to + /// skip already transformed instructions. + /// + public int IndexOfFirstAlreadyTransformedInstruction { get; set; } + public BlockTransformContext(ILTransformContext context) : base(context) { } @@ -96,27 +106,36 @@ public void Run(ILFunction function, ILTransformContext context) } } - void VisitBlock(ControlFlowNode cfgNode, BlockTransformContext context) + /// + /// Walks the dominator tree rooted at entryNode, calling the transforms on each block. + /// + void VisitBlock(ControlFlowNode entryNode, BlockTransformContext context) { - Block block = (Block)cfgNode.UserData; - context.StepStartGroup(block.Label, block); + IEnumerable Preorder(ControlFlowNode cfgNode) + { + // preorder processing: + Block block = (Block)cfgNode.UserData; + context.StepStartGroup(block.Label, block); - context.ControlFlowNode = cfgNode; - context.Block = block; - block.RunTransforms(PreOrderTransforms, context); + context.ControlFlowNode = cfgNode; + context.Block = block; + context.IndexOfFirstAlreadyTransformedInstruction = block.Instructions.Count; + block.RunTransforms(PreOrderTransforms, context); - // First, process the children in the dominator tree. - // The ConditionDetection transform requires dominated blocks to - // be already processed. - foreach (var child in cfgNode.DominatorTreeChildren) - { - VisitBlock(child, context); + // process the children + return cfgNode.DominatorTreeChildren; } - context.ControlFlowNode = cfgNode; - context.Block = block; - block.RunTransforms(PostOrderTransforms, context); - context.StepEndGroup(); + foreach (var cfgNode in TreeTraversal.PostOrder(entryNode, Preorder)) + { + // in post-order: + Block block = (Block)cfgNode.UserData; + context.ControlFlowNode = cfgNode; + context.Block = block; + context.IndexOfFirstAlreadyTransformedInstruction = block.Instructions.Count; + block.RunTransforms(PostOrderTransforms, context); + context.StepEndGroup(); + } } } } diff --git a/ICSharpCode.Decompiler/IL/Transforms/CachedDelegateInitialization.cs b/ICSharpCode.Decompiler/IL/Transforms/CachedDelegateInitialization.cs index 59a49c78d1..4bfa3a9963 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/CachedDelegateInitialization.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/CachedDelegateInitialization.cs @@ -16,7 +16,6 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -using System; using System.Linq; using ICSharpCode.Decompiler.TypeSystem; @@ -32,36 +31,42 @@ public void Run(Block block, BlockTransformContext context) this.context = context; if (!context.Settings.AnonymousMethods) return; - for (int i = block.Instructions.Count - 1; i >= 0; i--) + for (int i = context.IndexOfFirstAlreadyTransformedInstruction - 1; i >= 0; i--) { if (block.Instructions[i] is IfInstruction inst) { if (CachedDelegateInitializationWithField(inst)) { block.Instructions.RemoveAt(i); + context.IndexOfFirstAlreadyTransformedInstruction = block.Instructions.Count; continue; } if (CachedDelegateInitializationWithLocal(inst)) { ILInlining.InlineOneIfPossible(block, i, InliningOptions.Aggressive, context); + context.IndexOfFirstAlreadyTransformedInstruction = block.Instructions.Count; continue; } if (CachedDelegateInitializationRoslynInStaticWithLocal(inst) || CachedDelegateInitializationRoslynWithLocal(inst)) { block.Instructions.RemoveAt(i); + context.IndexOfFirstAlreadyTransformedInstruction = block.Instructions.Count; continue; } if (CachedDelegateInitializationVB(inst)) { + context.IndexOfFirstAlreadyTransformedInstruction = block.Instructions.Count; continue; } if (CachedDelegateInitializationVBWithReturn(inst)) { block.Instructions.RemoveAt(i); + context.IndexOfFirstAlreadyTransformedInstruction = block.Instructions.Count; continue; } if (CachedDelegateInitializationVBWithClosure(inst)) { + context.IndexOfFirstAlreadyTransformedInstruction = block.Instructions.Count; continue; } } diff --git a/ICSharpCode.Decompiler/IL/Transforms/HighLevelLoopTransform.cs b/ICSharpCode.Decompiler/IL/Transforms/HighLevelLoopTransform.cs index d69ae9881e..d912ae2478 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/HighLevelLoopTransform.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/HighLevelLoopTransform.cs @@ -92,8 +92,11 @@ bool MatchWhileLoop(BlockContainer loop, out IfInstruction condition, out Block ifInstruction.Condition = Comp.LogicNot(ifInstruction.Condition); ifInstruction.FalseInst = ifInstruction.TrueInst; //move the rest of the body into a new block - loopBody = ConditionDetection.ExtractBlock(loop.EntryPoint, 1, loop.EntryPoint.Instructions.Count); + loopBody = new Block(); + loopBody.AddRef(); + ConditionDetection.ExtractBlock(loop.EntryPoint, 1, loop.EntryPoint.Instructions.Count, loopBody); loop.Blocks.Insert(1, loopBody); + loopBody.ReleaseRef(); if (!loopBody.HasFlag(InstructionFlags.EndPointUnreachable)) loopBody.Instructions.Add(new Leave(loop)); diff --git a/ICSharpCode.Decompiler/IL/Transforms/LockTransform.cs b/ICSharpCode.Decompiler/IL/Transforms/LockTransform.cs index 5863db1686..084c3bd797 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/LockTransform.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/LockTransform.cs @@ -16,12 +16,6 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - using ICSharpCode.Decompiler.TypeSystem; namespace ICSharpCode.Decompiler.IL.Transforms @@ -35,18 +29,39 @@ void IBlockTransform.Run(Block block, BlockTransformContext context) if (!context.Settings.LockStatement) return; this.context = context; - for (int i = block.Instructions.Count - 1; i >= 0; i--) + for (int i = context.IndexOfFirstAlreadyTransformedInstruction - 1; i >= 0; i--) { - if (!TransformLockRoslyn(block, i)) - if (!TransformLockV4(block, i)) - if (!TransformLockV4YieldReturn(block, i)) - if (!TransformLockV2(block, i)) - TransformLockMCS(block, i); + bool changed = DoTransform(block, i); + if (changed) + { + context.IndexOfFirstAlreadyTransformedInstruction = block.Instructions.Count; + } // This happens in some cases: // Use correct index after transformation. if (i >= block.Instructions.Count) i = block.Instructions.Count; } + + bool DoTransform(Block block, int i) + { + if (TransformLockRoslyn(block, i)) + { + return true; + } + if (TransformLockV4(block, i)) + { + return true; + } + if (TransformLockV4YieldReturn(block, i)) + { + return true; + } + if (TransformLockV2(block, i)) + { + return true; + } + return TransformLockMCS(block, i); + } } /// diff --git a/ICSharpCode.Decompiler/IL/Transforms/StatementTransform.cs b/ICSharpCode.Decompiler/IL/Transforms/StatementTransform.cs index 59a8dbbbdf..60fd4e3254 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/StatementTransform.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/StatementTransform.cs @@ -114,7 +114,11 @@ public void Run(Block block, BlockTransformContext context) { var ctx = new StatementTransformContext(context); int pos = 0; - ctx.rerunPosition = block.Instructions.Count - 1; + if (context.IndexOfFirstAlreadyTransformedInstruction == 0) + { + return; + } + ctx.rerunPosition = context.IndexOfFirstAlreadyTransformedInstruction - 1; while (pos >= 0) { if (ctx.rerunPosition != null) diff --git a/ICSharpCode.Decompiler/IL/Transforms/TransformAssignment.cs b/ICSharpCode.Decompiler/IL/Transforms/TransformAssignment.cs index c666467502..a24783d214 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/TransformAssignment.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/TransformAssignment.cs @@ -132,6 +132,9 @@ bool TransformInlineAssignmentStObjOrCall(Block block, int pos) } if (block.Instructions[nextPos] is StObj stobj) { + // unaligned.stobj cannot be inlined in C# + if (stobj.UnalignedPrefix > 0) + return false; if (!stobj.Value.MatchLdLoc(inst.Variable)) return false; if (!SemanticHelper.IsPure(stobj.Target.Flags) || inst.Variable.IsUsedWithin(stobj.Target)) diff --git a/ICSharpCode.Decompiler/IL/Transforms/UsingTransform.cs b/ICSharpCode.Decompiler/IL/Transforms/UsingTransform.cs index 2025d390b1..8a61d7931c 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/UsingTransform.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/UsingTransform.cs @@ -16,11 +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; using System.Linq; -using System.Text; -using System.Threading.Tasks; using ICSharpCode.Decompiler.TypeSystem; @@ -35,18 +31,21 @@ void IBlockTransform.Run(Block block, BlockTransformContext context) if (!context.Settings.UsingStatement) return; this.context = context; - for (int i = block.Instructions.Count - 1; i >= 0; i--) + for (int i = context.IndexOfFirstAlreadyTransformedInstruction - 1; i >= 0; i--) { if (TransformUsing(block, i)) { + context.IndexOfFirstAlreadyTransformedInstruction = block.Instructions.Count; continue; } if (TransformUsingVB(block, i)) { + context.IndexOfFirstAlreadyTransformedInstruction = block.Instructions.Count; continue; } if (TransformAsyncUsing(block, i)) { + context.IndexOfFirstAlreadyTransformedInstruction = block.Instructions.Count; continue; } } diff --git a/ICSharpCode.Decompiler/Metadata/DotNetCorePathFinder.cs b/ICSharpCode.Decompiler/Metadata/DotNetCorePathFinder.cs index 18a50f0d2a..67f266c54c 100644 --- a/ICSharpCode.Decompiler/Metadata/DotNetCorePathFinder.cs +++ b/ICSharpCode.Decompiler/Metadata/DotNetCorePathFinder.cs @@ -60,7 +60,8 @@ public DotNetCorePackageInfo(string fullName, string type, string path, string[] } static readonly string[] LookupPaths = new string[] { - Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".nuget", "packages") + Environment.GetEnvironmentVariable("NUGET_PACKAGES"), + Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".nuget", "packages") }; static readonly string[] RuntimePacks = new[] { @@ -109,6 +110,10 @@ public DotNetCorePathFinder(string parentAssemblyFileName, string targetFramewor foreach (var path in LookupPaths) { + if (string.IsNullOrWhiteSpace(path)) + { + continue; + } foreach (var p in packages) { foreach (var item in p.RuntimeComponents) diff --git a/ICSharpCode.Decompiler/Metadata/MetadataExtensions.cs b/ICSharpCode.Decompiler/Metadata/MetadataExtensions.cs index 445d0dffd6..5ce6beafa4 100644 --- a/ICSharpCode.Decompiler/Metadata/MetadataExtensions.cs +++ b/ICSharpCode.Decompiler/Metadata/MetadataExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Buffers.Binary; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; @@ -384,11 +385,13 @@ public static IEnumerable GetMethodSpecifications(thi yield return Read(row); } - unsafe (Handle Handle, MethodSemanticsAttributes Semantics, MethodDefinitionHandle Method, EntityHandle Association) Read(int row) + (Handle Handle, MethodSemanticsAttributes Semantics, MethodDefinitionHandle Method, EntityHandle Association) Read(int row) { - byte* ptr = metadata.MetadataPointer + offset + rowSize * row; - int methodDef = methodSmall ? *(ushort*)(ptr + 2) : (int)*(uint*)(ptr + 2); - int assocDef = assocSmall ? *(ushort*)(ptr + assocOffset) : (int)*(uint*)(ptr + assocOffset); + var span = metadata.AsReadOnlySpan(); + var methodDefSpan = span.Slice(offset + rowSize * row + 2); + int methodDef = methodSmall ? BinaryPrimitives.ReadUInt16LittleEndian(methodDefSpan) : (int)BinaryPrimitives.ReadUInt32LittleEndian(methodDefSpan); + var assocSpan = span.Slice(assocOffset); + int assocDef = assocSmall ? BinaryPrimitives.ReadUInt16LittleEndian(assocSpan) : (int)BinaryPrimitives.ReadUInt32LittleEndian(assocSpan); EntityHandle propOrEvent; if ((assocDef & 0x1) == 1) { @@ -398,7 +401,7 @@ public static IEnumerable GetMethodSpecifications(thi { propOrEvent = MetadataTokens.EventDefinitionHandle(assocDef >> 1); } - return (MetadataTokens.Handle(0x18000000 | (row + 1)), (MethodSemanticsAttributes)(*(ushort*)ptr), MetadataTokens.MethodDefinitionHandle(methodDef), propOrEvent); + return (MetadataTokens.Handle(0x18000000 | (row + 1)), (MethodSemanticsAttributes)(BinaryPrimitives.ReadUInt16LittleEndian(span)), MetadataTokens.MethodDefinitionHandle(methodDef), propOrEvent); } } @@ -411,9 +414,9 @@ public static IEnumerable GetFieldLayouts(this MetadataReader meta } } - public unsafe static (int Offset, FieldDefinitionHandle FieldDef) GetFieldLayout(this MetadataReader metadata, EntityHandle fieldLayoutHandle) + public static (int Offset, FieldDefinitionHandle FieldDef) GetFieldLayout(this MetadataReader metadata, EntityHandle fieldLayoutHandle) { - byte* startPointer = metadata.MetadataPointer; + var startPointer = metadata.AsReadOnlySpan(); int offset = metadata.GetTableMetadataOffset(TableIndex.FieldLayout); int rowSize = metadata.GetTableRowSize(TableIndex.FieldLayout); int rowCount = metadata.GetTableRowCount(TableIndex.FieldLayout); @@ -422,14 +425,31 @@ public unsafe static (int Offset, FieldDefinitionHandle FieldDef) GetFieldLayout bool small = metadata.GetTableRowCount(TableIndex.Field) <= ushort.MaxValue; for (int row = rowCount - 1; row >= 0; row--) { - byte* ptr = startPointer + offset + rowSize * row; - uint rowNo = small ? *(ushort*)(ptr + 4) : *(uint*)(ptr + 4); + ReadOnlySpan ptr = startPointer.Slice(offset + rowSize * row); + var rowNoSpan = ptr.Slice(4); + uint rowNo = small ? BinaryPrimitives.ReadUInt16LittleEndian(rowNoSpan) : BinaryPrimitives.ReadUInt32LittleEndian(rowNoSpan); if (fieldRowNo == rowNo) { - return (*(int*)ptr, MetadataTokens.FieldDefinitionHandle(fieldRowNo)); + return (BinaryPrimitives.ReadInt32LittleEndian(ptr), MetadataTokens.FieldDefinitionHandle(fieldRowNo)); } } return (0, default); } + + public static ReadOnlySpan AsReadOnlySpan(this MetadataReader metadataReader) + { + unsafe + { + return new(metadataReader.MetadataPointer, metadataReader.MetadataLength); + } + } + + public static BlobReader AsBlobReader(this MetadataReader metadataReader) + { + unsafe + { + return new(metadataReader.MetadataPointer, metadataReader.MetadataLength); + } + } } } diff --git a/ICSharpCode.Decompiler/Properties/DecompilerVersionInfo.template.cs b/ICSharpCode.Decompiler/Properties/DecompilerVersionInfo.template.cs index 3271d1034a..5472ee6d0b 100644 --- a/ICSharpCode.Decompiler/Properties/DecompilerVersionInfo.template.cs +++ b/ICSharpCode.Decompiler/Properties/DecompilerVersionInfo.template.cs @@ -1,10 +1,10 @@ public static class DecompilerVersionInfo { - public const string Major = "8"; - public const string Minor = "2"; + public const string Major = "9"; + public const string Minor = "0"; public const string Build = "0"; public const string Revision = "$INSERTREVISION$"; - public const string VersionName = null; + public const string VersionName = "preview1"; public const string FullVersion = Major + "." + Minor + "." + Build + ".$INSERTREVISION$$INSERTBRANCHPOSTFIX$$INSERTVERSIONNAMEPOSTFIX$"; public const string FullVersionWithShortCommitHash = FullVersion + "-$INSERTSHORTCOMMITHASH$"; diff --git a/ICSharpCode.Decompiler/TypeSystem/ApplyAttributeTypeVisitor.cs b/ICSharpCode.Decompiler/TypeSystem/ApplyAttributeTypeVisitor.cs index a6ba7ef15d..0ad2985139 100644 --- a/ICSharpCode.Decompiler/TypeSystem/ApplyAttributeTypeVisitor.cs +++ b/ICSharpCode.Decompiler/TypeSystem/ApplyAttributeTypeVisitor.cs @@ -40,7 +40,8 @@ public static IType ApplyAttributesToType( SRM.MetadataReader metadata, TypeSystemOptions options, Nullability nullableContext, - bool typeChildrenOnly = false) + bool typeChildrenOnly = false, + SRM.CustomAttributeHandleCollection? additionalAttributes = null) { bool hasDynamicAttribute = false; bool[] dynamicAttributeData = null; @@ -57,73 +58,87 @@ public static IType ApplyAttributesToType( { nullability = Nullability.Oblivious; } - const TypeSystemOptions relevantOptions = TypeSystemOptions.Dynamic | TypeSystemOptions.Tuple | TypeSystemOptions.NullabilityAnnotations | TypeSystemOptions.NativeIntegers; - if (attributes != null && (options & relevantOptions) != 0) + + void ProcessAttribute(SRM.CustomAttributeHandle attrHandle) { - foreach (var attrHandle in attributes.Value) + var attr = metadata.GetCustomAttribute(attrHandle); + var attrType = attr.GetAttributeType(metadata); + if ((options & TypeSystemOptions.Dynamic) != 0 && attrType.IsKnownType(metadata, KnownAttribute.Dynamic)) { - var attr = metadata.GetCustomAttribute(attrHandle); - var attrType = attr.GetAttributeType(metadata); - if ((options & TypeSystemOptions.Dynamic) != 0 && attrType.IsKnownType(metadata, KnownAttribute.Dynamic)) + hasDynamicAttribute = true; + var ctor = attr.DecodeValue(Metadata.MetadataExtensions.minimalCorlibTypeProvider); + if (ctor.FixedArguments.Length == 1) { - hasDynamicAttribute = true; - var ctor = attr.DecodeValue(Metadata.MetadataExtensions.minimalCorlibTypeProvider); - if (ctor.FixedArguments.Length == 1) + var arg = ctor.FixedArguments[0]; + if (arg.Value is ImmutableArray> values + && values.All(v => v.Value is bool)) { - var arg = ctor.FixedArguments[0]; - if (arg.Value is ImmutableArray> values - && values.All(v => v.Value is bool)) - { - dynamicAttributeData = values.SelectArray(v => (bool)v.Value); - } + dynamicAttributeData = values.SelectArray(v => (bool)v.Value); } } - else if ((options & TypeSystemOptions.NativeIntegers) != 0 && attrType.IsKnownType(metadata, KnownAttribute.NativeInteger)) + } + else if ((options & TypeSystemOptions.NativeIntegers) != 0 && attrType.IsKnownType(metadata, KnownAttribute.NativeInteger)) + { + hasNativeIntegersAttribute = true; + var ctor = attr.DecodeValue(Metadata.MetadataExtensions.minimalCorlibTypeProvider); + if (ctor.FixedArguments.Length == 1) { - hasNativeIntegersAttribute = true; - var ctor = attr.DecodeValue(Metadata.MetadataExtensions.minimalCorlibTypeProvider); - if (ctor.FixedArguments.Length == 1) + var arg = ctor.FixedArguments[0]; + if (arg.Value is ImmutableArray> values + && values.All(v => v.Value is bool)) { - var arg = ctor.FixedArguments[0]; - if (arg.Value is ImmutableArray> values - && values.All(v => v.Value is bool)) - { - nativeIntegersAttributeData = values.SelectArray(v => (bool)v.Value); - } + nativeIntegersAttributeData = values.SelectArray(v => (bool)v.Value); } } - else if ((options & TypeSystemOptions.Tuple) != 0 && attrType.IsKnownType(metadata, KnownAttribute.TupleElementNames)) + } + else if ((options & TypeSystemOptions.Tuple) != 0 && attrType.IsKnownType(metadata, KnownAttribute.TupleElementNames)) + { + var ctor = attr.DecodeValue(Metadata.MetadataExtensions.minimalCorlibTypeProvider); + if (ctor.FixedArguments.Length == 1) { - var ctor = attr.DecodeValue(Metadata.MetadataExtensions.minimalCorlibTypeProvider); - if (ctor.FixedArguments.Length == 1) + var arg = ctor.FixedArguments[0]; + if (arg.Value is ImmutableArray> values + && values.All(v => v.Value is string || v.Value == null)) { - var arg = ctor.FixedArguments[0]; - if (arg.Value is ImmutableArray> values - && values.All(v => v.Value is string || v.Value == null)) - { - tupleElementNames = values.SelectArray(v => (string)v.Value); - } + tupleElementNames = values.SelectArray(v => (string)v.Value); } } - else if ((options & TypeSystemOptions.NullabilityAnnotations) != 0 && attrType.IsKnownType(metadata, KnownAttribute.Nullable)) + } + else if ((options & TypeSystemOptions.NullabilityAnnotations) != 0 && attrType.IsKnownType(metadata, KnownAttribute.Nullable)) + { + var ctor = attr.DecodeValue(Metadata.MetadataExtensions.minimalCorlibTypeProvider); + if (ctor.FixedArguments.Length == 1) { - var ctor = attr.DecodeValue(Metadata.MetadataExtensions.minimalCorlibTypeProvider); - if (ctor.FixedArguments.Length == 1) + var arg = ctor.FixedArguments[0]; + if (arg.Value is ImmutableArray> values + && values.All(v => v.Value is byte b && b <= 2)) { - var arg = ctor.FixedArguments[0]; - if (arg.Value is ImmutableArray> values - && values.All(v => v.Value is byte b && b <= 2)) - { - nullableAttributeData = values.SelectArray(v => (Nullability)(byte)v.Value); - } - else if (arg.Value is byte b && b <= 2) - { - nullability = (Nullability)b; - } + nullableAttributeData = values.SelectArray(v => (Nullability)(byte)v.Value); + } + else if (arg.Value is byte b && b <= 2) + { + nullability = (Nullability)b; } } } } + + const TypeSystemOptions relevantOptions = TypeSystemOptions.Dynamic | TypeSystemOptions.Tuple | TypeSystemOptions.NullabilityAnnotations | TypeSystemOptions.NativeIntegers; + if (attributes != null && (options & relevantOptions) != 0) + { + foreach (var attrHandle in attributes.Value) + { + ProcessAttribute(attrHandle); + } + } + if (additionalAttributes != null && (options & relevantOptions) != 0) + { + // Note: additional attributes will override the values from the normal attributes. + foreach (var attrHandle in additionalAttributes.Value) + { + ProcessAttribute(attrHandle); + } + } if (hasDynamicAttribute || hasNativeIntegersAttribute || nullability != Nullability.Oblivious || nullableAttributeData != null || (options & (TypeSystemOptions.Tuple | TypeSystemOptions.KeepModifiers)) != TypeSystemOptions.KeepModifiers) { diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs index 84be4ccb6e..7964a590ed 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs @@ -209,13 +209,14 @@ internal static (IType returnType, IParameter[] parameters, ModifiedType returnT MetadataModule module, IParameterizedMember owner, MethodSignature signature, ParameterHandleCollection? parameterHandles, Nullability nullableContext, TypeSystemOptions typeSystemOptions, - CustomAttributeHandleCollection? returnTypeAttributes = null) + CustomAttributeHandleCollection? additionalReturnTypeAttributes = null) { var metadata = module.metadata; int i = 0; IParameter[] parameters = new IParameter[signature.RequiredParameterCount + (signature.Header.CallingConvention == SignatureCallingConvention.VarArgs ? 1 : 0)]; IType parameterType; + CustomAttributeHandleCollection? returnTypeAttributes = null; if (parameterHandles != null) { foreach (var parameterHandle in parameterHandles) @@ -225,13 +226,12 @@ internal static (IType returnType, IParameter[] parameters, ModifiedType returnT { // "parameter" holds return type attributes. // Note: for properties, the attributes normally stored on a method's return type - // are instead stored as normal attributes on the property. - // So MetadataProperty provides a non-null value for returnTypeAttributes, - // which then should be preferred over the attributes on the accessor's parameters. - if (returnTypeAttributes == null) - { - returnTypeAttributes = par.GetCustomAttributes(); - } + // are instead typically stored as normal attributes on the property. + // So MetadataProperty provides a non-null value for additionalReturnTypeAttributes, + // which then will be preferred over the attributes on the accessor's parameters. + // However if an attribute only exists on the accessor's parameters, we still want + // to process it here. + returnTypeAttributes = par.GetCustomAttributes(); } else if (i < par.SequenceNumber && par.SequenceNumber <= signature.RequiredParameterCount) { @@ -271,7 +271,8 @@ internal static (IType returnType, IParameter[] parameters, ModifiedType returnT } Debug.Assert(i == parameters.Length); var returnType = ApplyAttributeTypeVisitor.ApplyAttributesToType(signature.ReturnType, - module.Compilation, returnTypeAttributes, metadata, typeSystemOptions, nullableContext); + module.Compilation, returnTypeAttributes, metadata, typeSystemOptions, nullableContext, + additionalAttributes: additionalReturnTypeAttributes); return (returnType, parameters, signature.ReturnType as ModifiedType); } #endregion diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataProperty.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataProperty.cs index 9269bead98..0dd339b994 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataProperty.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataProperty.cs @@ -169,7 +169,7 @@ private void DecodeSignature() (returnType, parameters, _) = MetadataMethod.DecodeSignature( module, this, signature, parameterHandles, nullableContext, typeOptions, - returnTypeAttributes: propertyDef.GetCustomAttributes()); + additionalReturnTypeAttributes: propertyDef.GetCustomAttributes()); } catch (BadImageFormatException) { diff --git a/ICSharpCode.Decompiler/TypeSystem/NormalizeTypeVisitor.cs b/ICSharpCode.Decompiler/TypeSystem/NormalizeTypeVisitor.cs index 8f097f6832..4d140715a7 100644 --- a/ICSharpCode.Decompiler/TypeSystem/NormalizeTypeVisitor.cs +++ b/ICSharpCode.Decompiler/TypeSystem/NormalizeTypeVisitor.cs @@ -50,6 +50,17 @@ sealed class NormalizeTypeVisitor : TypeVisitor RemoveNullability = true, }; + internal static readonly NormalizeTypeVisitor IgnoreNullability = new NormalizeTypeVisitor { + ReplaceClassTypeParametersWithDummy = false, + ReplaceMethodTypeParametersWithDummy = false, + DynamicAndObject = false, + IntPtrToNInt = false, + TupleToUnderlyingType = false, + RemoveModOpt = true, + RemoveModReq = true, + RemoveNullability = true, + }; + public bool EquivalentTypes(IType a, IType b) { a = a.AcceptVisitor(this); diff --git a/ICSharpCode.Decompiler/Util/BitOperations.cs b/ICSharpCode.Decompiler/Util/BitOperations.cs new file mode 100644 index 0000000000..d8d8934f5f --- /dev/null +++ b/ICSharpCode.Decompiler/Util/BitOperations.cs @@ -0,0 +1,52 @@ +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +#if !NETCORE +namespace System.Numerics +{ + internal static class BitOperations + { + private static ReadOnlySpan TrailingZeroCountDeBruijn => new byte[32] +{ + 00, 01, 28, 02, 29, 14, 24, 03, + 30, 22, 20, 15, 25, 17, 04, 08, + 31, 27, 13, 23, 21, 19, 16, 07, + 26, 12, 18, 06, 11, 05, 10, 09 +}; + public static int TrailingZeroCount(uint value) + { + // Unguarded fallback contract is 0->0, BSF contract is 0->undefined + if (value == 0) + { + return 32; + } + + unchecked + { + // uint.MaxValue >> 27 is always in range [0 - 31] so we use Unsafe.AddByteOffset to avoid bounds check + return Unsafe.AddByteOffset( + // Using deBruijn sequence, k=2, n=5 (2^5=32) : 0b_0000_0111_0111_1100_1011_0101_0011_0001u + ref MemoryMarshal.GetReference(TrailingZeroCountDeBruijn), + // uint|long -> IntPtr cast on 32-bit platforms does expensive overflow checks not needed here + (IntPtr)(int)(((value & (uint)-(int)value) * 0x077CB531u) >> 27)); // Multi-cast mitigates redundant conv.u8 + } + } + + public static int TrailingZeroCount(ulong value) + { + unchecked + { + uint lo = (uint)value; + + if (lo == 0) + { + return 32 + TrailingZeroCount((uint)(value >> 32)); + } + + return TrailingZeroCount(lo); + } + } + } +} +#endif diff --git a/ICSharpCode.Decompiler/Util/BitSet.cs b/ICSharpCode.Decompiler/Util/BitSet.cs index 5d7ecf4293..3980c1f81d 100644 --- a/ICSharpCode.Decompiler/Util/BitSet.cs +++ b/ICSharpCode.Decompiler/Util/BitSet.cs @@ -18,7 +18,9 @@ #nullable enable using System; +using System.Collections.Generic; using System.Diagnostics; +using System.Numerics; using System.Text; namespace ICSharpCode.Decompiler.Util @@ -268,6 +270,63 @@ public void ClearAll() } } + public int NextSetBit(int startIndex, int endIndex) + { + Debug.Assert(startIndex <= endIndex); + if (startIndex >= endIndex) + { + return -1; + } + + int startWordIndex = WordIndex(startIndex); + int endWordIndex = WordIndex(endIndex - 1); + ulong startMask = Mask << startIndex; + ulong endMask = Mask >> -endIndex; // same as (Mask >> (64 - (endIndex % 64))) + if (startWordIndex == endWordIndex) + { + ulong maskedWord = words[startWordIndex] & startMask & endMask; + if (maskedWord != 0) + { + return startWordIndex * 64 + BitOperations.TrailingZeroCount(maskedWord); + } + } + else + { + ulong maskedWord = words[startWordIndex] & startMask; + if (maskedWord != 0) + { + return startWordIndex * 64 + BitOperations.TrailingZeroCount(maskedWord); + } + for (int i = startWordIndex + 1; i < endWordIndex; i++) + { + maskedWord = words[i]; + if (maskedWord != 0) + { + return i * 64 + BitOperations.TrailingZeroCount(maskedWord); + } + } + maskedWord = words[endWordIndex] & endMask; + if (maskedWord != 0) + { + return endWordIndex * 64 + BitOperations.TrailingZeroCount(maskedWord); + } + } + + return -1; + } + + public IEnumerable SetBits(int startIndex, int endIndex) + { + while (true) + { + int next = NextSetBit(startIndex, endIndex); + if (next == -1) + break; + yield return next; + startIndex = next + 1; + } + } + public void ReplaceWith(BitSet incoming) { Debug.Assert(words.Length == incoming.words.Length); diff --git a/ICSharpCode.Decompiler/Util/CollectionExtensions.cs b/ICSharpCode.Decompiler/Util/CollectionExtensions.cs index 11be785b9c..2912707ec7 100644 --- a/ICSharpCode.Decompiler/Util/CollectionExtensions.cs +++ b/ICSharpCode.Decompiler/Util/CollectionExtensions.cs @@ -21,6 +21,12 @@ public static void Deconstruct(this KeyValuePair pair, out K key, ou } #endif + public static IEnumerable<(int, A, B)> ZipWithIndex(this IEnumerable input1, IEnumerable input2) + { + int index = 0; + return input1.Zip(input2, (a, b) => (index++, a, b)); + } + public static IEnumerable<(A?, B?)> ZipLongest(this IEnumerable input1, IEnumerable input2) { using (var it1 = input1.GetEnumerator()) diff --git a/ICSharpCode.Decompiler/Util/GraphTraversal.cs b/ICSharpCode.Decompiler/Util/GraphTraversal.cs new file mode 100644 index 0000000000..a2dc4c7b25 --- /dev/null +++ b/ICSharpCode.Decompiler/Util/GraphTraversal.cs @@ -0,0 +1,116 @@ +// Copyright (c) 2023 Daniel Grunwald +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +#nullable enable + +using System; +using System.Collections.Generic; + +namespace ICSharpCode.Decompiler.Util; + +static class GraphTraversal +{ + /// + /// Depth-first-search of an graph data structure. + /// The two callbacks (successorFunc + postorderAction) will be called exactly once for each node reachable from startNodes. + /// + /// The start nodes. + /// Called multiple times per node. The first call should return true, subsequent calls must return false. + /// The first calls to this function occur in pre-order. + /// If null, normal Equals/GetHashCode will be used to compare nodes. + /// The function that gets the successors of an element. Called in pre-order. + /// Called in post-order. + /// + /// With reverse_successors=True, the start_nodes and each list of successors will be handled in reverse order. + /// This is useful if the post-order will be reversed later (e.g. for a topological sort) + /// so that blocks which could be output in either order (e.g. then-block and else-block of an if) + /// will maintain the order of the edges (then-block before else-block). + /// + public static void DepthFirstSearch(IEnumerable startNodes, Func? visitedFunc, Func?> successorFunc, Action? postorderAction = null, bool reverseSuccessors = false) + { + /* + Pseudocode: + def dfs_walk(start_nodes, successor_func, visited, postorder_func, reverse_successors): + if reverse_successors: + start_nodes = reversed(start_nodes) + for node in start_nodes: + if node in visited: continue + visited.insert(node) + children = successor_func(node) + dfs_walk(children, successor_func, visited, postorder_action, reverse_successors) + postorder_action(node) + + The actual implementation here is equivalent but does not use recursion, + so that we don't blow the stack on large graphs. + A single stack holds the "continuations" of work that needs to be done. + These can be either "visit continuations" (=execute the body of the pseudocode + loop for the given node) or "postorder continuations" (=execute postorder_action) + */ + // Use a List as stack (but allowing for the Reverse() usage) + var worklist = new List<(T node, bool isPostOrderContinuation)>(); + visitedFunc ??= new HashSet().Add; + foreach (T node in startNodes) + { + worklist.Add((node, false)); + } + if (!reverseSuccessors) + { + // Our use of a stack will reverse the order of the nodes. + // If that's not desired, restore original order by reversing twice. + worklist.Reverse(); + } + // Process outstanding continuations: + while (worklist.Count > 0) + { + var (node, isPostOrderContinuation) = worklist.Last(); + if (isPostOrderContinuation) + { + // Execute postorder_action + postorderAction?.Invoke(node); + worklist.RemoveAt(worklist.Count - 1); + continue; + } + // Execute body of loop + if (!visitedFunc(node)) + { + // Already visited + worklist.RemoveAt(worklist.Count - 1); + continue; + } + // foreach-loop-iteration will end with postorder_func call, + // so switch the type of continuation for this node + int oldWorkListSize = worklist.Count; + worklist[oldWorkListSize - 1] = (node, true); + // Create "visit continuations" for all successor nodes: + IEnumerable? children = successorFunc(node); + if (children != null) + { + foreach (T child in children) + { + worklist.Add((child, false)); + } + } + // Our use of a stack will reverse the order of the nodes. + // If that's not desired, restore original order by reversing twice. + if (!reverseSuccessors) + { + worklist.Reverse(oldWorkListSize, worklist.Count - oldWorkListSize); + } + } + } +} diff --git a/ICSharpCode.ILSpyCmd/DotNetToolUpdateChecker.cs b/ICSharpCode.ILSpyCmd/DotNetToolUpdateChecker.cs index 449cceb827..79b3d921c9 100644 --- a/ICSharpCode.ILSpyCmd/DotNetToolUpdateChecker.cs +++ b/ICSharpCode.ILSpyCmd/DotNetToolUpdateChecker.cs @@ -11,6 +11,8 @@ namespace ICSharpCode.ILSpyCmd { + internal record PackageCheckResult(NuGetVersion RunningVersion, NuGetVersion LatestVersion, bool UpdateRecommendation); + // Idea from https://github.com/ErikEJ/EFCorePowerTools/blob/master/src/GUI/efcpt/Services/PackageService.cs internal static class DotNetToolUpdateChecker { @@ -20,7 +22,7 @@ static NuGetVersion CurrentPackageVersion() .InformationalVersion); } - public static async Task CheckForPackageUpdateAsync(string packageId) + public static async Task CheckForPackageUpdateAsync(string packageId) { try { @@ -35,10 +37,10 @@ public static async Task CheckForPackageUpdateAsync(string package CancellationToken.None).ConfigureAwait(false); var latestVersion = versions.Where(v => v.Release == "").MaxBy(v => v); - if (latestVersion > CurrentPackageVersion()) - { - return latestVersion; - } + var runningVersion = CurrentPackageVersion(); + int comparisonResult = latestVersion.CompareTo(runningVersion, VersionComparison.Version); + + return new PackageCheckResult(runningVersion, latestVersion, comparisonResult > 0); } #pragma warning disable RCS1075 // Avoid empty catch clause that catches System.Exception. catch (Exception) diff --git a/ICSharpCode.ILSpyCmd/ICSharpCode.ILSpyCmd.csproj b/ICSharpCode.ILSpyCmd/ICSharpCode.ILSpyCmd.csproj index c97d0e6505..ca25d2eef7 100644 --- a/ICSharpCode.ILSpyCmd/ICSharpCode.ILSpyCmd.csproj +++ b/ICSharpCode.ILSpyCmd/ICSharpCode.ILSpyCmd.csproj @@ -2,7 +2,7 @@ Exe - net6.0 + net8.0 true true true @@ -37,8 +37,6 @@ NU1605 - - @@ -49,9 +47,9 @@ - - - + + + diff --git a/ICSharpCode.ILSpyCmd/IlspyCmdProgram.cs b/ICSharpCode.ILSpyCmd/IlspyCmdProgram.cs index 8413fdfc4d..425357cac2 100644 --- a/ICSharpCode.ILSpyCmd/IlspyCmdProgram.cs +++ b/ICSharpCode.ILSpyCmd/IlspyCmdProgram.cs @@ -124,7 +124,7 @@ public ILSpyCmdProgram(IHostEnvironment env) private async Task OnExecuteAsync(CommandLineApplication app) { - Task updateCheckTask = null; + Task updateCheckTask = null; if (!DisableUpdateCheck) { updateCheckTask = DotNetToolUpdateChecker.CheckForPackageUpdateAsync("ilspycmd"); @@ -181,11 +181,11 @@ private async Task OnExecuteAsync(CommandLineApplication app) if (null != updateCheckTask) { - var latestVersion = await updateCheckTask; - if (null != latestVersion) + var checkResult = await updateCheckTask; + if (null != checkResult && checkResult.UpdateRecommendation) { Console.WriteLine("You are not using the latest version of the tool, please update."); - Console.WriteLine($"Latest version is '{latestVersion}'"); + Console.WriteLine($"Latest version is '{checkResult.LatestVersion}' (yours is '{checkResult.RunningVersion}')"); } } } diff --git a/ICSharpCode.ILSpyX/AssemblyList.cs b/ICSharpCode.ILSpyX/AssemblyList.cs index 90123d6432..d7070498ba 100644 --- a/ICSharpCode.ILSpyX/AssemblyList.cs +++ b/ICSharpCode.ILSpyX/AssemblyList.cs @@ -23,7 +23,6 @@ using System.Collections.ObjectModel; using System.Collections.Specialized; using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Threading; @@ -395,6 +394,16 @@ public void Unload(LoadedAssembly assembly) } } + public void Clear() + { + VerifyAccess(); + lock (lockObj) + { + dirty = true; + assemblies.Clear(); + byFilename.Clear(); + } + } public void Sort(IComparer comparer) { Sort(0, int.MaxValue, comparer); diff --git a/ICSharpCode.ILSpyX/ICSharpCode.ILSpyX.csproj b/ICSharpCode.ILSpyX/ICSharpCode.ILSpyX.csproj index 86b9a2503b..a788e3659d 100644 --- a/ICSharpCode.ILSpyX/ICSharpCode.ILSpyX.csproj +++ b/ICSharpCode.ILSpyX/ICSharpCode.ILSpyX.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 enable true nullable @@ -44,8 +44,6 @@ - - @@ -64,12 +62,12 @@ - - - - - - + + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/ICSharpCode.ILSpyX/PdbProvider/MonoCecilDebugInfoProvider.cs b/ICSharpCode.ILSpyX/PdbProvider/MonoCecilDebugInfoProvider.cs index c7e09d3053..6fe3021bbb 100644 --- a/ICSharpCode.ILSpyX/PdbProvider/MonoCecilDebugInfoProvider.cs +++ b/ICSharpCode.ILSpyX/PdbProvider/MonoCecilDebugInfoProvider.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2018 Siegfried Pammer +// Copyright (c) 2018 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 @@ -135,5 +135,13 @@ public bool TryGetName(SRM.MethodDefinitionHandle handle, int index, [NotNullWhe name = variable.Name; return name != null; } + + public bool TryGetExtraTypeInfo(SRM.MethodDefinitionHandle method, int index, out PdbExtraTypeInfo extraTypeInfo) + { + // Mono.Cecil's WindowsPDB reader is unable to read tuple element names + // and dynamic flags custom debug information. + extraTypeInfo = default; + return false; + } } } diff --git a/ICSharpCode.ILSpyX/PdbProvider/PortableDebugInfoProvider.cs b/ICSharpCode.ILSpyX/PdbProvider/PortableDebugInfoProvider.cs index 0f64997ea6..5cacbbe6dc 100644 --- a/ICSharpCode.ILSpyX/PdbProvider/PortableDebugInfoProvider.cs +++ b/ICSharpCode.ILSpyX/PdbProvider/PortableDebugInfoProvider.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2018 Siegfried Pammer +// Copyright (c) 2018 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 @@ -161,5 +161,77 @@ public bool TryGetName(MethodDefinitionHandle method, int index, [NotNullWhen(tr } return false; } + + public bool TryGetExtraTypeInfo(MethodDefinitionHandle method, int index, out PdbExtraTypeInfo extraTypeInfo) + { + var metadata = GetMetadataReader(); + extraTypeInfo = default; + + if (metadata == null) + return false; + + LocalVariableHandle localVariableHandle = default; + foreach (var h in metadata.GetLocalScopes(method)) + { + var scope = metadata.GetLocalScope(h); + foreach (var v in scope.GetLocalVariables()) + { + var var = metadata.GetLocalVariable(v); + if (var.Index == index) + { + localVariableHandle = v; + break; + } + } + + if (!localVariableHandle.IsNil) + break; + } + + foreach (var h in metadata.CustomDebugInformation) + { + var cdi = metadata.GetCustomDebugInformation(h); + if (cdi.Parent.IsNil || cdi.Parent.Kind != HandleKind.LocalVariable) + continue; + if (localVariableHandle != (LocalVariableHandle)cdi.Parent) + continue; + if (cdi.Value.IsNil || cdi.Kind.IsNil) + continue; + var kind = metadata.GetGuid(cdi.Kind); + if (kind == KnownGuids.TupleElementNames && extraTypeInfo.TupleElementNames is null) + { + var reader = metadata.GetBlobReader(cdi.Value); + var list = new List(); + while (reader.RemainingBytes > 0) + { + // Read a UTF8 null-terminated string + int length = reader.IndexOf(0); + string s = reader.ReadUTF8(length); + // Skip null terminator + reader.ReadByte(); + list.Add(string.IsNullOrWhiteSpace(s) ? null : s); + } + + extraTypeInfo.TupleElementNames = list.ToArray(); + } + else if (kind == KnownGuids.DynamicLocalVariables && extraTypeInfo.DynamicFlags is null) + { + var reader = metadata.GetBlobReader(cdi.Value); + extraTypeInfo.DynamicFlags = new bool[reader.Length * 8]; + int j = 0; + while (reader.RemainingBytes > 0) + { + int b = reader.ReadByte(); + for (int i = 1; i < 0x100; i <<= 1) + extraTypeInfo.DynamicFlags[j++] = (b & i) != 0; + } + } + + if (extraTypeInfo.TupleElementNames != null && extraTypeInfo.DynamicFlags != null) + break; + } + + return extraTypeInfo.TupleElementNames != null || extraTypeInfo.DynamicFlags != null; + } } } diff --git a/ICSharpCode.ILSpyX/Search/AbstractEntitySearchStrategy.cs b/ICSharpCode.ILSpyX/Search/AbstractEntitySearchStrategy.cs index 036004b1d4..803c5f9528 100644 --- a/ICSharpCode.ILSpyX/Search/AbstractEntitySearchStrategy.cs +++ b/ICSharpCode.ILSpyX/Search/AbstractEntitySearchStrategy.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Concurrent; +using System.IO; namespace ICSharpCode.ILSpyX.Search { @@ -66,7 +67,9 @@ protected bool IsInNamespaceOrAssembly(IEntity entity) { if (searchRequest.InAssembly != null) { - if (entity.ParentModule == null || !entity.ParentModule.FullAssemblyName.Contains(searchRequest.InAssembly, StringComparison.OrdinalIgnoreCase)) + if (entity.ParentModule?.PEFile == null || + !(Path.GetFileName(entity.ParentModule.PEFile.FileName).Contains(searchRequest.InAssembly, StringComparison.OrdinalIgnoreCase) + || entity.ParentModule.FullAssemblyName.Contains(searchRequest.InAssembly, StringComparison.OrdinalIgnoreCase))) { return false; } diff --git a/ILSpy.AddIn.VS2022/ILSpy.AddIn.VS2022.csproj b/ILSpy.AddIn.VS2022/ILSpy.AddIn.VS2022.csproj index 5d09db6572..e0d1db28c2 100644 --- a/ILSpy.AddIn.VS2022/ILSpy.AddIn.VS2022.csproj +++ b/ILSpy.AddIn.VS2022/ILSpy.AddIn.VS2022.csproj @@ -34,7 +34,9 @@ true - + + false + @@ -45,14 +47,14 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + - + @@ -74,8 +76,8 @@ - ..\ILSpy\bin\$(Configuration)\net6.0-windows\win-x64\publish\fwdependent\ - ..\ILSpy\bin\$(Configuration)\net6.0-windows\win-arm64\publish\fwdependent\ + ..\ILSpy\bin\$(Configuration)\net8.0-windows\win-x64\publish\fwdependent\ + ..\ILSpy\bin\$(Configuration)\net8.0-windows\win-arm64\publish\fwdependent\ diff --git a/ILSpy.AddIn/ILSpy.AddIn.csproj b/ILSpy.AddIn/ILSpy.AddIn.csproj index 021cfed03e..5ad17dfb59 100644 --- a/ILSpy.AddIn/ILSpy.AddIn.csproj +++ b/ILSpy.AddIn/ILSpy.AddIn.csproj @@ -39,7 +39,9 @@ - + + false + @@ -51,14 +53,14 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + - + @@ -80,16 +82,16 @@ - ..\ILSpy\bin\$(Configuration)\net6.0-windows\win-x64\publish\fwdependent\ + ..\ILSpy\bin\$(Configuration)\net8.0-windows\win-x64\publish\fwdependent\ - \ILSpy\zh-Hans\ + \x64\ILSpy\zh-Hans\ - \ILSpy + \x64\ILSpy diff --git a/ILSpy.BamlDecompiler.Tests/BamlTestRunner.cs b/ILSpy.BamlDecompiler.Tests/BamlTestRunner.cs index 27acff4ca8..9ed326403b 100644 --- a/ILSpy.BamlDecompiler.Tests/BamlTestRunner.cs +++ b/ILSpy.BamlDecompiler.Tests/BamlTestRunner.cs @@ -179,7 +179,7 @@ void RunTest(string name, string asmPath, string sourcePath) resolver.AddSearchDirectory(Path.GetDirectoryName(asmPath)); var res = module.Resources.First(); Stream bamlStream = LoadBaml(res, name + ".baml"); - Assert.IsNotNull(bamlStream); + Assert.That(bamlStream, Is.Not.Null); BamlDecompilerTypeSystem typeSystem = new BamlDecompilerTypeSystem(module, resolver); var decompiler = new XamlDecompiler(typeSystem, new BamlDecompilerSettings()); diff --git a/ILSpy.BamlDecompiler.Tests/ILSpy.BamlDecompiler.Tests.csproj b/ILSpy.BamlDecompiler.Tests/ILSpy.BamlDecompiler.Tests.csproj index dc979f1526..b8a51da296 100644 --- a/ILSpy.BamlDecompiler.Tests/ILSpy.BamlDecompiler.Tests.csproj +++ b/ILSpy.BamlDecompiler.Tests/ILSpy.BamlDecompiler.Tests.csproj @@ -2,7 +2,7 @@ - net6.0-windows + net8.0-windows win-x64 false AutoGeneratedProgram @@ -28,15 +28,13 @@ true - - - - - - - - + + + + + + diff --git a/ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj b/ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj index e222ba25a0..8658ab8334 100644 --- a/ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj +++ b/ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj @@ -2,7 +2,7 @@ ILSpy.BamlDecompiler.Plugin - net6.0-windows + net8.0-windows win-x64;win-arm64 false False @@ -26,8 +26,6 @@ ..\ILSpy\bin\$(Configuration)\ - - diff --git a/ILSpy.Installer/ILSpy.Installer.csproj b/ILSpy.Installer/ILSpy.Installer.csproj index 0697d38728..c8f84010cd 100644 --- a/ILSpy.Installer/ILSpy.Installer.csproj +++ b/ILSpy.Installer/ILSpy.Installer.csproj @@ -10,6 +10,10 @@ $(DefineConstants);$(PlatformForInstaller) + + false + + diff --git a/ILSpy.Installer/setup.cs b/ILSpy.Installer/setup.cs index ce15c30891..0bcc418d63 100644 --- a/ILSpy.Installer/setup.cs +++ b/ILSpy.Installer/setup.cs @@ -25,7 +25,7 @@ static public void Main() #else var buildPlatform = "x64"; #endif - var buildOutputDir = $@"ILSpy\bin\{buildConfiguration}\net6.0-windows\win-{buildPlatform}\publish\fwdependent"; + var buildOutputDir = $@"ILSpy\bin\{buildConfiguration}\net8.0-windows\win-{buildPlatform}\publish\fwdependent"; var project = new Project("ILSpy", new InstallDir(@"%LocalAppData%\Programs\ILSpy", diff --git a/ILSpy.ReadyToRun/ILSpy.ReadyToRun.csproj b/ILSpy.ReadyToRun/ILSpy.ReadyToRun.csproj index f0a708b217..5b894464ad 100644 --- a/ILSpy.ReadyToRun/ILSpy.ReadyToRun.csproj +++ b/ILSpy.ReadyToRun/ILSpy.ReadyToRun.csproj @@ -3,7 +3,7 @@ ILSpy.ReadyToRun.Plugin - net6.0-windows + net8.0-windows win-x64;win-arm64 False en-US @@ -34,18 +34,16 @@ - - - - + + - - + + diff --git a/ILSpy.Tests/Analyzers/MemberImplementsInterfaceAnalyzerTests.cs b/ILSpy.Tests/Analyzers/MemberImplementsInterfaceAnalyzerTests.cs index f9616006c3..f3d2f3c933 100644 --- a/ILSpy.Tests/Analyzers/MemberImplementsInterfaceAnalyzerTests.cs +++ b/ILSpy.Tests/Analyzers/MemberImplementsInterfaceAnalyzerTests.cs @@ -69,7 +69,7 @@ public void VerifyDoesNotShowForNoSymbol() var shouldShow = analyzer.Show(symbol: null); // Assert - Assert.IsFalse(shouldShow, $"The analyzer will be unexpectedly shown for no symbol"); + Assert.That(!shouldShow, $"The analyzer will be unexpectedly shown for no symbol"); } [Test] @@ -85,7 +85,7 @@ public void VerifyDoesNotShowForNonMembers(SymbolKind symbolKind) var shouldShow = analyzer.Show(symbolMock); // Assert - Assert.IsFalse(shouldShow, $"The analyzer will be unexpectedly shown for symbol '{symbolKind}'"); + Assert.That(!shouldShow, $"The analyzer will be unexpectedly shown for symbol '{symbolKind}'"); } [Test] @@ -100,7 +100,7 @@ public void VerifyDoesNotShowForStaticMembers(SymbolKind symbolKind) var shouldShow = analyzer.Show(memberMock); // Assert - Assert.IsFalse(shouldShow, $"The analyzer will be unexpectedly shown for static symbol '{symbolKind}'"); + Assert.That(!shouldShow, $"The analyzer will be unexpectedly shown for static symbol '{symbolKind}'"); } [Test] @@ -117,7 +117,7 @@ public void VerifyDoesNotShowForUnsupportedTypes( var shouldShow = analyzer.Show(memberMock); // Assert - Assert.IsFalse(shouldShow, $"The analyzer will be unexpectedly shown for symbol '{symbolKind}' and '{typeKind}'"); + Assert.That(!shouldShow, $"The analyzer will be unexpectedly shown for symbol '{symbolKind}' and '{typeKind}'"); } [Test] @@ -134,7 +134,7 @@ public void VerifyShowsForSupportedTypes( var shouldShow = analyzer.Show(memberMock); // Assert - Assert.IsTrue(shouldShow, $"The analyzer will not be shown for symbol '{symbolKind}' and '{typeKind}'"); + Assert.That(shouldShow, $"The analyzer will not be shown for symbol '{symbolKind}' and '{typeKind}'"); } [Test] @@ -148,13 +148,13 @@ public void VerifyReturnsOnlyInterfaceMembers() var results = analyzer.Analyze(symbol, new AnalyzerContext()); // Assert - Assert.IsNotNull(results); - Assert.AreEqual(1, results.Count()); + Assert.That(results, Is.Not.Null); + Assert.That(results.Count(), Is.EqualTo(1)); var result = results.FirstOrDefault() as IMethod; - Assert.IsNotNull(result); - Assert.IsNotNull(result.DeclaringTypeDefinition); - Assert.AreEqual(TypeKind.Interface, result.DeclaringTypeDefinition.Kind); - Assert.AreEqual(nameof(ITestInterface), result.DeclaringTypeDefinition.Name); + Assert.That(result, Is.Not.Null); + Assert.That(result.DeclaringTypeDefinition, Is.Not.Null); + Assert.That(result.DeclaringTypeDefinition.Kind, Is.EqualTo(TypeKind.Interface)); + Assert.That(result.DeclaringTypeDefinition.Name, Is.EqualTo(nameof(ITestInterface))); } private ISymbol SetupSymbolForAnalysis(Type type, string methodName) diff --git a/ILSpy.Tests/Analyzers/MethodUsesAnalyzerTests.cs b/ILSpy.Tests/Analyzers/MethodUsesAnalyzerTests.cs index 0f9f46cbbf..9cd7726d65 100644 --- a/ILSpy.Tests/Analyzers/MethodUsesAnalyzerTests.cs +++ b/ILSpy.Tests/Analyzers/MethodUsesAnalyzerTests.cs @@ -42,11 +42,11 @@ public void MainAssemblyUsesSystemStringEmpty() var results = new MethodUsesAnalyzer().Analyze(symbol, context).ToList(); - Assert.IsTrue(results.Count == 1); + Assert.That(results.Count == 1); var field = results.Single() as IField; - Assert.IsNotNull(field); - Assert.IsFalse(field.MetadataToken.IsNil); - Assert.AreEqual(field.FullName, "System.String.Empty"); + Assert.That(field, Is.Not.Null); + Assert.That(!field.MetadataToken.IsNil); + Assert.That("System.String.Empty", Is.EqualTo(field.FullName)); } } } diff --git a/ILSpy.Tests/Analyzers/TypeUsedByAnalyzerTests.cs b/ILSpy.Tests/Analyzers/TypeUsedByAnalyzerTests.cs index 76af5ca9c9..b89a02d486 100644 --- a/ILSpy.Tests/Analyzers/TypeUsedByAnalyzerTests.cs +++ b/ILSpy.Tests/Analyzers/TypeUsedByAnalyzerTests.cs @@ -59,10 +59,10 @@ public void SystemInt32UsedByMainAssembly() var results = new TypeUsedByAnalyzer().Analyze(symbol, context).ToList(); - Assert.IsNotEmpty(results); + Assert.That(results, Is.Not.Empty); var method = results.OfType().SingleOrDefault(m => m.FullName == "ICSharpCode.ILSpy.Tests.Analyzers.TestCases.Main.MainAssembly.UsesInt32"); - Assert.IsNotNull(method); - Assert.IsFalse(method.MetadataToken.IsNil); + Assert.That(method, Is.Not.Null); + Assert.That(!method.MetadataToken.IsNil); } } } diff --git a/ILSpy.Tests/ILSpy.Tests.csproj b/ILSpy.Tests/ILSpy.Tests.csproj index 9178ceb434..5bb3d121fb 100644 --- a/ILSpy.Tests/ILSpy.Tests.csproj +++ b/ILSpy.Tests/ILSpy.Tests.csproj @@ -2,7 +2,7 @@ - net6.0-windows + net8.0-windows false AutoGeneratedProgram @@ -40,25 +40,23 @@ - - - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - + + + + + + + + + + diff --git a/ILSpy/Analyzers/AnalyzerEntityTreeNode.cs b/ILSpy/Analyzers/AnalyzerEntityTreeNode.cs index 782821c47c..930cb382c7 100644 --- a/ILSpy/Analyzers/AnalyzerEntityTreeNode.cs +++ b/ILSpy/Analyzers/AnalyzerEntityTreeNode.cs @@ -36,7 +36,7 @@ public abstract class AnalyzerEntityTreeNode : AnalyzerTreeNode, IMemberTreeNode public override void ActivateItem(System.Windows.RoutedEventArgs e) { e.Handled = true; - if (this.Member.MetadataToken.IsNil) + if (this.Member == null || this.Member.MetadataToken.IsNil) { MessageBox.Show(Properties.Resources.CannotAnalyzeMissingRef, "ILSpy"); return; diff --git a/ILSpy/Analyzers/AnalyzerScope.cs b/ILSpy/Analyzers/AnalyzerScope.cs index 6377549b2e..4560ce535e 100644 --- a/ILSpy/Analyzers/AnalyzerScope.cs +++ b/ILSpy/Analyzers/AnalyzerScope.cs @@ -54,16 +54,7 @@ public AnalyzerScope(AssemblyList assemblyList, IEntity entity) AssemblyList = assemblyList; assemblyListSnapshot = assemblyList.GetSnapshot(); AnalyzedSymbol = entity; - if (entity is ITypeDefinition type) - { - typeScope = type; - effectiveAccessibility = DetermineEffectiveAccessibility(ref typeScope, Accessibility.Public); - } - else - { - typeScope = entity.DeclaringTypeDefinition; - effectiveAccessibility = DetermineEffectiveAccessibility(ref typeScope, entity.Accessibility); - } + DetermineEffectiveAccessibility(entity, out typeScope, out effectiveAccessibility); IsLocal = effectiveAccessibility.LessThanOrEqual(Accessibility.Private); } @@ -112,20 +103,31 @@ public IEnumerable GetTypesInScope(CancellationToken ct) } } - static Accessibility DetermineEffectiveAccessibility(ref ITypeDefinition typeScope, Accessibility memberAccessibility) + static void DetermineEffectiveAccessibility(IEntity input, out ITypeDefinition typeScope, out Accessibility accessibility) { - Accessibility accessibility = memberAccessibility; - var ts = typeScope; - while (ts != null && !accessibility.LessThanOrEqual(Accessibility.Private)) + if (input is ITypeDefinition td) + { + accessibility = Accessibility.Public; + typeScope = td; + } + else { - accessibility = accessibility.Intersect(ts.Accessibility); - typeScope = ts; - ts = ts.DeclaringTypeDefinition; + accessibility = input.Accessibility; + typeScope = input.DeclaringTypeDefinition; } // Once we reach a private entity, we leave the loop with typeScope set to the class that // contains the private entity = the scope that needs to be searched. // Otherwise (if we don't find a private entity) we return the top-level class. - return accessibility; + var prevTypeScope = typeScope; + while (typeScope != null && !accessibility.LessThanOrEqual(Accessibility.Private)) + { + accessibility = accessibility.Intersect(typeScope.Accessibility); + typeScope = prevTypeScope.DeclaringTypeDefinition; + } + if (typeScope == null) + { + typeScope = prevTypeScope; + } } #region Find modules diff --git a/ILSpy/Analyzers/TreeNodes/AnalyzedModuleTreeNode.cs b/ILSpy/Analyzers/TreeNodes/AnalyzedModuleTreeNode.cs index 23bb562e98..5718a85bcc 100644 --- a/ILSpy/Analyzers/TreeNodes/AnalyzedModuleTreeNode.cs +++ b/ILSpy/Analyzers/TreeNodes/AnalyzedModuleTreeNode.cs @@ -18,9 +18,9 @@ using System; using System.Linq; +using System.Windows; using ICSharpCode.Decompiler.TypeSystem; -using ICSharpCode.ILSpy.TreeNodes; namespace ICSharpCode.ILSpy.Analyzers.TreeNodes { @@ -51,6 +51,17 @@ protected override void LoadChildren() } } + public override void ActivateItem(RoutedEventArgs e) + { + e.Handled = true; + if (analyzedModule.PEFile == null) + { + MessageBox.Show(Properties.Resources.CannotAnalyzeMissingRef, "ILSpy"); + return; + } + MainWindow.Instance.JumpToReference(analyzedModule.PEFile); + } + public override IEntity Member => null; } } diff --git a/ILSpy/Commands/RemoveAssembliesWithLoadErrors.cs b/ILSpy/Commands/RemoveAssembliesWithLoadErrors.cs index a0ca794791..a2a4430be0 100644 --- a/ILSpy/Commands/RemoveAssembliesWithLoadErrors.cs +++ b/ILSpy/Commands/RemoveAssembliesWithLoadErrors.cs @@ -16,8 +16,6 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -using System; -using System.Collections.Generic; using System.Linq; using ICSharpCode.ILSpy.Properties; @@ -44,4 +42,18 @@ public override void Execute(object parameter) } } } + + [ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.ClearAssemblyList), MenuCategory = nameof(Resources.Remove), MenuOrder = 2.6)] + class ClearAssemblyList : SimpleCommand + { + public override bool CanExecute(object parameter) + { + return MainWindow.Instance.CurrentAssemblyList?.Count > 0; + } + + public override void Execute(object parameter) + { + MainWindow.Instance.CurrentAssemblyList?.Clear(); + } + } } diff --git a/ILSpy/Controls/SearchBox.cs b/ILSpy/Controls/SearchBox.cs index b36640e1c5..4795bbe11b 100644 --- a/ILSpy/Controls/SearchBox.cs +++ b/ILSpy/Controls/SearchBox.cs @@ -99,6 +99,15 @@ protected override void OnTextChanged(TextChangedEventArgs e) timer.Stop(); timer.Interval = this.UpdateDelay; timer.Start(); + + UpdateWatermarkLabel(); + } + + private void UpdateWatermarkLabel() + { + Label wl = (Label)GetTemplateChild("WatermarkLabel"); + if (wl != null) + wl.Visibility = HasText ? Visibility.Hidden : Visibility.Visible; } void timer_Tick(object sender, EventArgs e) @@ -114,25 +123,13 @@ void timer_Tick(object sender, EventArgs e) protected override void OnLostFocus(RoutedEventArgs e) { - if (!HasText) - { - Label wl = (Label)GetTemplateChild("WatermarkLabel"); - if (wl != null) - wl.Visibility = Visibility.Visible; - } - + UpdateWatermarkLabel(); base.OnLostFocus(e); } protected override void OnGotFocus(RoutedEventArgs e) { - if (!HasText) - { - Label wl = (Label)GetTemplateChild("WatermarkLabel"); - if (wl != null) - wl.Visibility = Visibility.Hidden; - } - + UpdateWatermarkLabel(); base.OnGotFocus(e); } diff --git a/ILSpy/ILSpy.csproj b/ILSpy/ILSpy.csproj index d33163bad0..5e8184796c 100644 --- a/ILSpy/ILSpy.csproj +++ b/ILSpy/ILSpy.csproj @@ -3,7 +3,7 @@ WinExe - net6.0-windows + net8.0-windows win-x64;win-arm64 False false @@ -19,9 +19,14 @@ True ..\ICSharpCode.Decompiler\ICSharpCode.Decompiler.snk true + 1 true + + + + full true @@ -37,15 +42,13 @@ ..\ICSharpCode.Decompiler\ICSharpCode.Decompiler.ruleset - - - - - - - - + + + + + + @@ -86,7 +89,9 @@ - + + + diff --git a/ILSpy/Languages/CSharpLanguage.cs b/ILSpy/Languages/CSharpLanguage.cs index 144a7a456a..b098c8c4ad 100644 --- a/ILSpy/Languages/CSharpLanguage.cs +++ b/ILSpy/Languages/CSharpLanguage.cs @@ -24,13 +24,10 @@ using System.Reflection; using System.Reflection.Metadata; using System.Reflection.PortableExecutable; -using System.Text; using System.Windows; using System.Windows.Controls; -using ICSharpCode.AvalonEdit.Document; using ICSharpCode.AvalonEdit.Highlighting; -using ICSharpCode.AvalonEdit.Utils; using ICSharpCode.Decompiler; using ICSharpCode.Decompiler.CSharp; using ICSharpCode.Decompiler.CSharp.OutputVisitor; @@ -42,7 +39,6 @@ using ICSharpCode.Decompiler.Solution; using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.Util; -using ICSharpCode.ILSpy.Options; using ICSharpCode.ILSpy.TextView; using ICSharpCode.ILSpy.TreeNodes; using ICSharpCode.ILSpyX; @@ -426,7 +422,7 @@ public override ProjectId DecompileAssembly(LoadedAssembly assembly, ITextOutput if (globalType != null) { output.Write("// Global type: "); - output.WriteReference(globalType, globalType.FullName); + output.WriteReference(globalType, EscapeName(globalType.FullName)); output.WriteLine(); } var metadata = module.Metadata; @@ -438,7 +434,7 @@ public override ProjectId DecompileAssembly(LoadedAssembly assembly, ITextOutput if (entrypoint != null) { output.Write("// Entry point: "); - output.WriteReference(entrypoint, entrypoint.DeclaringType.FullName + "." + entrypoint.Name); + output.WriteReference(entrypoint, EscapeName(entrypoint.DeclaringType.FullName + "." + entrypoint.Name)); output.WriteLine(); } } @@ -615,30 +611,30 @@ public override string EventToString(IEvent @event, bool includeDeclaringTypeNam return EntityToString(@event, includeDeclaringTypeName, includeNamespace, includeNamespaceOfDeclaringTypeName); } - string ToCSharpString(MetadataReader metadata, TypeDefinitionHandle handle, bool fullName, bool omitGenerics) + static string ToCSharpString(MetadataReader metadata, TypeDefinitionHandle handle, bool fullName, bool omitGenerics) { - StringBuilder builder = new StringBuilder(); var currentTypeDefHandle = handle; var typeDef = metadata.GetTypeDefinition(currentTypeDefHandle); + List builder = new List(); while (!currentTypeDefHandle.IsNil) { - if (builder.Length > 0) - builder.Insert(0, '.'); + if (builder.Count > 0) + builder.Add("."); typeDef = metadata.GetTypeDefinition(currentTypeDefHandle); var part = ReflectionHelper.SplitTypeParameterCountFromReflectionName(metadata.GetString(typeDef.Name), out int typeParamCount); var genericParams = typeDef.GetGenericParameters(); if (!omitGenerics && genericParams.Count > 0) { - builder.Insert(0, '>'); + builder.Add(">"); int firstIndex = genericParams.Count - typeParamCount; for (int i = genericParams.Count - 1; i >= genericParams.Count - typeParamCount; i--) { - builder.Insert(0, metadata.GetString(metadata.GetGenericParameter(genericParams[i]).Name)); - builder.Insert(0, i == firstIndex ? '<' : ','); + builder.Add(metadata.GetString(metadata.GetGenericParameter(genericParams[i]).Name)); + builder.Add(i == firstIndex ? "<" : ","); } } - builder.Insert(0, part); + builder.Add(part); currentTypeDefHandle = typeDef.GetDeclaringType(); if (!fullName) break; @@ -646,11 +642,26 @@ string ToCSharpString(MetadataReader metadata, TypeDefinitionHandle handle, bool if (fullName && !typeDef.Namespace.IsNil) { - builder.Insert(0, '.'); - builder.Insert(0, metadata.GetString(typeDef.Namespace)); + builder.Add("."); + builder.Add(metadata.GetString(typeDef.Namespace)); } - return builder.ToString(); + switch (builder.Count) + { + case 0: + return string.Empty; + case 1: + return builder[0]; + case 2: + return builder[1] + builder[0]; + case 3: + return builder[2] + builder[1] + builder[0]; + case 4: + return builder[3] + builder[2] + builder[1] + builder[0]; + default: + builder.Reverse(); + return string.Concat(builder); + } } public override string GetEntityName(PEFile module, EntityHandle handle, bool fullName, bool omitGenerics) diff --git a/ILSpy/Metadata/CorTables/ClassLayoutTableTreeNode.cs b/ILSpy/Metadata/CorTables/ClassLayoutTableTreeNode.cs index af78f30442..bc939f1bca 100644 --- a/ILSpy/Metadata/CorTables/ClassLayoutTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/ClassLayoutTableTreeNode.cs @@ -16,6 +16,8 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +using System; +using System.Buffers.Binary; using System.Collections.Generic; using System.Reflection.Metadata; using System.Reflection.Metadata.Ecma335; @@ -38,7 +40,7 @@ public ClassLayoutTableTreeNode(PEFile module) public override object Icon => Images.Literal; - public unsafe override bool View(ViewModels.TabPageModel tabPage) + public override bool View(ViewModels.TabPageModel tabPage) { tabPage.Title = Text.ToString(); tabPage.SupportsLanguageSwitching = false; @@ -49,7 +51,7 @@ public unsafe override bool View(ViewModels.TabPageModel tabPage) var list = new List(); var length = metadata.GetTableRowCount(TableIndex.ClassLayout); - byte* ptr = metadata.MetadataPointer; + ReadOnlySpan ptr = metadata.AsReadOnlySpan(); int metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; ClassLayoutEntry scrollTargetEntry = default; @@ -80,15 +82,15 @@ readonly struct ClassLayout public readonly EntityHandle Parent; public readonly uint ClassSize; - public unsafe ClassLayout(byte* ptr, int typeDefSize) + public ClassLayout(ReadOnlySpan ptr, int typeDefSize) { - PackingSize = (ushort)Helpers.GetValue(ptr, 2); - ClassSize = (uint)Helpers.GetValue(ptr + 2, 4); - Parent = MetadataTokens.TypeDefinitionHandle(Helpers.GetValue(ptr + 6, typeDefSize)); + PackingSize = BinaryPrimitives.ReadUInt16LittleEndian(ptr); + ClassSize = BinaryPrimitives.ReadUInt32LittleEndian(ptr.Slice(2, 4)); + Parent = MetadataTokens.TypeDefinitionHandle(Helpers.GetValueLittleEndian(ptr.Slice(6, typeDefSize))); } } - unsafe struct ClassLayoutEntry + struct ClassLayoutEntry { readonly PEFile module; readonly MetadataReader metadata; @@ -117,7 +119,7 @@ public void OnParentClick() [ColumnInfo("X8", Kind = ColumnKind.Other)] public uint ClassSize => classLayout.ClassSize; - public ClassLayoutEntry(PEFile module, byte* ptr, int metadataOffset, int row) + public ClassLayoutEntry(PEFile module, ReadOnlySpan ptr, int metadataOffset, int row) { this.module = module; this.metadata = module.Metadata; @@ -125,7 +127,7 @@ public ClassLayoutEntry(PEFile module, byte* ptr, int metadataOffset, int row) var rowOffset = metadata.GetTableMetadataOffset(TableIndex.ClassLayout) + metadata.GetTableRowSize(TableIndex.ClassLayout) * (row - 1); this.Offset = metadataOffset + rowOffset; - this.classLayout = new ClassLayout(ptr + rowOffset, metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4); + this.classLayout = new ClassLayout(ptr.Slice(rowOffset), metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4); this.parentTooltip = null; } } diff --git a/ILSpy/Metadata/CorTables/EventMapTableTreeNode.cs b/ILSpy/Metadata/CorTables/EventMapTableTreeNode.cs index ae08337084..1d94b78c21 100644 --- a/ILSpy/Metadata/CorTables/EventMapTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/EventMapTableTreeNode.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; using System.Reflection.Metadata; using System.Reflection.Metadata.Ecma335; @@ -38,7 +39,7 @@ public EventMapTableTreeNode(PEFile module) public override object Icon => Images.Literal; - public unsafe override bool View(ViewModels.TabPageModel tabPage) + public override bool View(ViewModels.TabPageModel tabPage) { tabPage.Title = Text.ToString(); tabPage.SupportsLanguageSwitching = false; @@ -50,7 +51,7 @@ public unsafe override bool View(ViewModels.TabPageModel tabPage) EventMapEntry scrollTargetEntry = default; var length = metadata.GetTableRowCount(TableIndex.EventMap); - byte* ptr = metadata.MetadataPointer; + ReadOnlySpan ptr = metadata.AsReadOnlySpan(); int metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; for (int rid = 1; rid <= length; rid++) { @@ -79,14 +80,14 @@ readonly struct EventMap public readonly TypeDefinitionHandle Parent; public readonly EventDefinitionHandle EventList; - public unsafe EventMap(byte* ptr, int typeDefSize, int eventDefSize) + public EventMap(ReadOnlySpan ptr, int typeDefSize, int eventDefSize) { - Parent = MetadataTokens.TypeDefinitionHandle(Helpers.GetValue(ptr, typeDefSize)); - EventList = MetadataTokens.EventDefinitionHandle(Helpers.GetValue(ptr + typeDefSize, eventDefSize)); + Parent = MetadataTokens.TypeDefinitionHandle(Helpers.GetValueLittleEndian(ptr.Slice(0, typeDefSize))); + EventList = MetadataTokens.EventDefinitionHandle(Helpers.GetValueLittleEndian(ptr.Slice(typeDefSize, eventDefSize))); } } - unsafe struct EventMapEntry + struct EventMapEntry { readonly PEFile module; readonly MetadataReader metadata; @@ -120,7 +121,7 @@ public void OnEventListClick() string eventListTooltip; public string EventListTooltip => GenerateTooltip(ref eventListTooltip, module, eventMap.EventList); - public EventMapEntry(PEFile module, byte* ptr, int metadataOffset, int row) + public EventMapEntry(PEFile module, ReadOnlySpan ptr, int metadataOffset, int row) { this.module = module; this.metadata = module.Metadata; @@ -130,7 +131,7 @@ public EventMapEntry(PEFile module, byte* ptr, int metadataOffset, int row) this.Offset = metadataOffset + rowOffset; int typeDefSize = metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4; int eventDefSize = metadata.GetTableRowCount(TableIndex.Event) < ushort.MaxValue ? 2 : 4; - this.eventMap = new EventMap(ptr + rowOffset, typeDefSize, eventDefSize); + this.eventMap = new EventMap(ptr.Slice(rowOffset), typeDefSize, eventDefSize); this.parentTooltip = null; this.eventListTooltip = null; } diff --git a/ILSpy/Metadata/CorTables/FieldLayoutTableTreeNode.cs b/ILSpy/Metadata/CorTables/FieldLayoutTableTreeNode.cs index 8a80966b0c..f5da959eb7 100644 --- a/ILSpy/Metadata/CorTables/FieldLayoutTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/FieldLayoutTableTreeNode.cs @@ -16,6 +16,8 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +using System; +using System.Buffers.Binary; using System.Collections.Generic; using System.Reflection.Metadata; using System.Reflection.Metadata.Ecma335; @@ -38,7 +40,7 @@ public FieldLayoutTableTreeNode(PEFile module) public override object Icon => Images.Literal; - public unsafe override bool View(ViewModels.TabPageModel tabPage) + public override bool View(ViewModels.TabPageModel tabPage) { tabPage.Title = Text.ToString(); tabPage.SupportsLanguageSwitching = false; @@ -50,7 +52,7 @@ public unsafe override bool View(ViewModels.TabPageModel tabPage) FieldLayoutEntry scrollTargetEntry = default; var length = metadata.GetTableRowCount(TableIndex.FieldLayout); - byte* ptr = metadata.MetadataPointer; + ReadOnlySpan ptr = metadata.AsReadOnlySpan(); int metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; for (int rid = 1; rid <= length; rid++) { @@ -79,14 +81,14 @@ readonly struct FieldLayout public readonly int Offset; public readonly FieldDefinitionHandle Field; - public unsafe FieldLayout(byte* ptr, int fieldDefSize) + public FieldLayout(ReadOnlySpan ptr, int fieldDefSize) { - Offset = Helpers.GetValue(ptr, 4); - Field = MetadataTokens.FieldDefinitionHandle(Helpers.GetValue(ptr + 4, fieldDefSize)); + Offset = BinaryPrimitives.ReadInt32LittleEndian(ptr); + Field = MetadataTokens.FieldDefinitionHandle(Helpers.GetValueLittleEndian(ptr.Slice(4, fieldDefSize))); } } - unsafe struct FieldLayoutEntry + struct FieldLayoutEntry { readonly PEFile module; readonly MetadataReader metadata; @@ -112,7 +114,7 @@ public void OnFieldClick() [ColumnInfo("X8", Kind = ColumnKind.Other)] public int FieldOffset => fieldLayout.Offset; - public FieldLayoutEntry(PEFile module, byte* ptr, int metadataOffset, int row) + public FieldLayoutEntry(PEFile module, ReadOnlySpan ptr, int metadataOffset, int row) { this.module = module; this.metadata = module.Metadata; @@ -121,7 +123,7 @@ public FieldLayoutEntry(PEFile module, byte* ptr, int metadataOffset, int row) + metadata.GetTableRowSize(TableIndex.FieldLayout) * (row - 1); this.Offset = metadataOffset + rowOffset; int fieldDefSize = metadata.GetTableRowCount(TableIndex.Field) < ushort.MaxValue ? 2 : 4; - this.fieldLayout = new FieldLayout(ptr + rowOffset, fieldDefSize); + this.fieldLayout = new FieldLayout(ptr.Slice(rowOffset), fieldDefSize); this.fieldTooltip = null; } } diff --git a/ILSpy/Metadata/CorTables/FieldMarshalTableTreeNode.cs b/ILSpy/Metadata/CorTables/FieldMarshalTableTreeNode.cs index a9f26ff130..b6cc9771eb 100644 --- a/ILSpy/Metadata/CorTables/FieldMarshalTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/FieldMarshalTableTreeNode.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; using System.Reflection.Metadata; using System.Reflection.Metadata.Ecma335; @@ -38,7 +39,7 @@ public FieldMarshalTableTreeNode(PEFile module) public override object Icon => Images.Literal; - public unsafe override bool View(ViewModels.TabPageModel tabPage) + public override bool View(ViewModels.TabPageModel tabPage) { tabPage.Title = Text.ToString(); tabPage.SupportsLanguageSwitching = false; @@ -50,7 +51,7 @@ public unsafe override bool View(ViewModels.TabPageModel tabPage) FieldMarshalEntry scrollTargetEntry = default; var length = metadata.GetTableRowCount(TableIndex.FieldMarshal); - byte* ptr = metadata.MetadataPointer; + ReadOnlySpan ptr = metadata.AsReadOnlySpan(); int metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; for (int rid = 1; rid <= length; rid++) { @@ -79,14 +80,14 @@ readonly struct FieldMarshal public readonly BlobHandle NativeType; public readonly EntityHandle Parent; - public unsafe FieldMarshal(byte* ptr, int blobHeapSize, int hasFieldMarshalRefSize) + public FieldMarshal(ReadOnlySpan ptr, int blobHeapSize, int hasFieldMarshalRefSize) { - Parent = Helpers.FromHasFieldMarshalTag((uint)Helpers.GetValue(ptr, hasFieldMarshalRefSize)); - NativeType = MetadataTokens.BlobHandle(Helpers.GetValue(ptr + hasFieldMarshalRefSize, blobHeapSize)); + Parent = Helpers.FromHasFieldMarshalTag((uint)Helpers.GetValueLittleEndian(ptr, hasFieldMarshalRefSize)); + NativeType = MetadataTokens.BlobHandle(Helpers.GetValueLittleEndian(ptr.Slice(hasFieldMarshalRefSize, blobHeapSize))); } } - unsafe struct FieldMarshalEntry + struct FieldMarshalEntry { readonly PEFile module; readonly MetadataReader metadata; @@ -112,7 +113,7 @@ public void OnParentClick() [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] public int NativeType => MetadataTokens.GetHeapOffset(fieldMarshal.NativeType); - public FieldMarshalEntry(PEFile module, byte* ptr, int metadataOffset, int row) + public FieldMarshalEntry(PEFile module, ReadOnlySpan ptr, int metadataOffset, int row) { this.module = module; this.metadata = module.Metadata; @@ -122,7 +123,7 @@ public FieldMarshalEntry(PEFile module, byte* ptr, int metadataOffset, int row) this.Offset = metadataOffset + rowOffset; int hasFieldMarshalRefSize = metadata.ComputeCodedTokenSize(32768, TableMask.Field | TableMask.Param); int blobHeapSize = metadata.GetHeapSize(HeapIndex.Blob) < ushort.MaxValue ? 2 : 4; - this.fieldMarshal = new FieldMarshal(ptr + rowOffset, blobHeapSize, hasFieldMarshalRefSize); + this.fieldMarshal = new FieldMarshal(ptr.Slice(rowOffset), blobHeapSize, hasFieldMarshalRefSize); this.parentTooltip = null; } } diff --git a/ILSpy/Metadata/CorTables/FieldRVATableTreeNode.cs b/ILSpy/Metadata/CorTables/FieldRVATableTreeNode.cs index 9317bb3367..dc34c5c23c 100644 --- a/ILSpy/Metadata/CorTables/FieldRVATableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/FieldRVATableTreeNode.cs @@ -16,6 +16,8 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +using System; +using System.Buffers.Binary; using System.Collections.Generic; using System.Reflection.Metadata; using System.Reflection.Metadata.Ecma335; @@ -38,7 +40,7 @@ public FieldRVATableTreeNode(PEFile module) public override object Icon => Images.Literal; - public unsafe override bool View(ViewModels.TabPageModel tabPage) + public override bool View(ViewModels.TabPageModel tabPage) { tabPage.Title = Text.ToString(); tabPage.SupportsLanguageSwitching = false; @@ -50,7 +52,7 @@ public unsafe override bool View(ViewModels.TabPageModel tabPage) FieldRVAEntry scrollTargetEntry = default; var length = metadata.GetTableRowCount(TableIndex.FieldRva); - byte* ptr = metadata.MetadataPointer; + ReadOnlySpan ptr = metadata.AsReadOnlySpan(); int metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; for (int rid = 1; rid <= length; rid++) { @@ -79,14 +81,14 @@ readonly struct FieldRVA public readonly int Offset; public readonly FieldDefinitionHandle Field; - public unsafe FieldRVA(byte* ptr, int fieldDefSize) + public FieldRVA(ReadOnlySpan ptr, int fieldDefSize) { - Offset = Helpers.GetValue(ptr, 4); - Field = MetadataTokens.FieldDefinitionHandle(Helpers.GetValue(ptr + 4, fieldDefSize)); + Offset = BinaryPrimitives.ReadInt32LittleEndian(ptr); + Field = MetadataTokens.FieldDefinitionHandle(Helpers.GetValueLittleEndian(ptr.Slice(4, fieldDefSize))); } } - unsafe struct FieldRVAEntry + struct FieldRVAEntry { readonly PEFile module; readonly MetadataReader metadata; @@ -112,7 +114,7 @@ public void OnFieldClick() [ColumnInfo("X8", Kind = ColumnKind.Other)] public int FieldOffset => fieldRVA.Offset; - public FieldRVAEntry(PEFile module, byte* ptr, int metadataOffset, int row) + public FieldRVAEntry(PEFile module, ReadOnlySpan ptr, int metadataOffset, int row) { this.module = module; this.metadata = module.Metadata; @@ -121,7 +123,7 @@ public FieldRVAEntry(PEFile module, byte* ptr, int metadataOffset, int row) + metadata.GetTableRowSize(TableIndex.FieldRva) * (row - 1); this.Offset = metadataOffset + rowOffset; int fieldDefSize = metadata.GetTableRowCount(TableIndex.Field) < ushort.MaxValue ? 2 : 4; - this.fieldRVA = new FieldRVA(ptr + rowOffset, fieldDefSize); + this.fieldRVA = new FieldRVA(ptr.Slice(rowOffset), fieldDefSize); this.fieldTooltip = null; } } diff --git a/ILSpy/Metadata/CorTables/ImplMapTableTreeNode.cs b/ILSpy/Metadata/CorTables/ImplMapTableTreeNode.cs index c6c228ba69..9a7642b25e 100644 --- a/ILSpy/Metadata/CorTables/ImplMapTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/ImplMapTableTreeNode.cs @@ -16,6 +16,8 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +using System; +using System.Buffers.Binary; using System.Collections.Generic; using System.Reflection.Metadata; using System.Reflection.Metadata.Ecma335; @@ -40,7 +42,9 @@ public ImplMapTableTreeNode(PEFile module) public override object Icon => Images.Literal; - public unsafe override bool View(ViewModels.TabPageModel tabPage) + + + public override bool View(ViewModels.TabPageModel tabPage) { tabPage.Title = Text.ToString(); tabPage.SupportsLanguageSwitching = false; @@ -52,11 +56,11 @@ public unsafe override bool View(ViewModels.TabPageModel tabPage) ImplMapEntry scrollTargetEntry = default; var length = metadata.GetTableRowCount(TableIndex.ImplMap); - byte* ptr = metadata.MetadataPointer; + var span = metadata.AsReadOnlySpan(); int metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; for (int rid = 1; rid <= length; rid++) { - ImplMapEntry entry = new ImplMapEntry(module, ptr, metadataOffset, rid); + ImplMapEntry entry = new ImplMapEntry(module, span, metadataOffset, rid); if (entry.RID == this.scrollTarget) { scrollTargetEntry = entry; @@ -83,16 +87,16 @@ readonly struct ImplMap public readonly StringHandle ImportName; public readonly ModuleReferenceHandle ImportScope; - public unsafe ImplMap(byte* ptr, int moduleRefSize, int memberForwardedTagRefSize, int stringHandleSize) + public ImplMap(ReadOnlySpan span, int moduleRefSize, int memberForwardedTagRefSize, int stringHandleSize) { - MappingFlags = (PInvokeAttributes)Helpers.GetValue(ptr, 2); - MemberForwarded = Helpers.FromMemberForwardedTag((uint)Helpers.GetValue(ptr + 2, memberForwardedTagRefSize)); - ImportName = MetadataTokens.StringHandle(Helpers.GetValue(ptr + 2 + memberForwardedTagRefSize, stringHandleSize)); - ImportScope = MetadataTokens.ModuleReferenceHandle(Helpers.GetValue(ptr + 2 + memberForwardedTagRefSize + stringHandleSize, moduleRefSize)); + MappingFlags = (PInvokeAttributes)BinaryPrimitives.ReadUInt16LittleEndian(span); + MemberForwarded = Helpers.FromMemberForwardedTag((uint)Helpers.GetValueLittleEndian(span.Slice(2, memberForwardedTagRefSize))); + ImportName = MetadataTokens.StringHandle(Helpers.GetValueLittleEndian(span.Slice(2 + memberForwardedTagRefSize, stringHandleSize))); + ImportScope = MetadataTokens.ModuleReferenceHandle(Helpers.GetValueLittleEndian(span.Slice(2 + memberForwardedTagRefSize + stringHandleSize, moduleRefSize))); } } - unsafe struct ImplMapEntry + struct ImplMapEntry { readonly PEFile module; readonly MetadataReader metadata; @@ -141,7 +145,7 @@ public void OnImportScopeClick() public string ImportNameTooltip => $"{MetadataTokens.GetHeapOffset(implMap.ImportName):X} \"{ImportName}\""; - public unsafe ImplMapEntry(PEFile module, byte* ptr, int metadataOffset, int row) + public ImplMapEntry(PEFile module, ReadOnlySpan span, int metadataOffset, int row) { this.module = module; this.metadata = module.Metadata; @@ -152,7 +156,7 @@ public unsafe ImplMapEntry(PEFile module, byte* ptr, int metadataOffset, int row int moduleRefSize = metadata.GetTableRowCount(TableIndex.ModuleRef) < ushort.MaxValue ? 2 : 4; int memberForwardedTagRefSize = metadata.ComputeCodedTokenSize(32768, TableMask.MethodDef | TableMask.Field); int stringHandleSize = metadata.GetHeapSize(HeapIndex.String) < ushort.MaxValue ? 2 : 4; - this.implMap = new ImplMap(ptr + rowOffset, moduleRefSize, memberForwardedTagRefSize, stringHandleSize); + this.implMap = new ImplMap(span.Slice(rowOffset), moduleRefSize, memberForwardedTagRefSize, stringHandleSize); this.importScopeTooltip = null; this.memberForwardedTooltip = null; } diff --git a/ILSpy/Metadata/CorTables/InterfaceImplTableTreeNode.cs b/ILSpy/Metadata/CorTables/InterfaceImplTableTreeNode.cs index 35c66ab850..e1ea243bfb 100644 --- a/ILSpy/Metadata/CorTables/InterfaceImplTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/InterfaceImplTableTreeNode.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; using System.Reflection.Metadata; using System.Reflection.Metadata.Ecma335; @@ -38,7 +39,7 @@ public InterfaceImplTableTreeNode(PEFile module) public override object Icon => Images.Literal; - public unsafe override bool View(ViewModels.TabPageModel tabPage) + public override bool View(ViewModels.TabPageModel tabPage) { tabPage.Title = Text.ToString(); tabPage.SupportsLanguageSwitching = false; @@ -50,7 +51,7 @@ public unsafe override bool View(ViewModels.TabPageModel tabPage) InterfaceImplEntry scrollTargetEntry = default; var length = metadata.GetTableRowCount(TableIndex.InterfaceImpl); - byte* ptr = metadata.MetadataPointer; + ReadOnlySpan ptr = metadata.AsReadOnlySpan(); int metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; for (int rid = 1; rid <= length; rid++) { @@ -79,14 +80,14 @@ readonly struct InterfaceImpl public readonly EntityHandle Class; public readonly EntityHandle Interface; - public unsafe InterfaceImpl(byte* ptr, int classSize, int interfaceSize) + public InterfaceImpl(ReadOnlySpan ptr, int classSize, int interfaceSize) { - Class = MetadataTokens.TypeDefinitionHandle(Helpers.GetValue(ptr, classSize)); - Interface = Helpers.FromTypeDefOrRefTag((uint)Helpers.GetValue(ptr + classSize, interfaceSize)); + Class = MetadataTokens.TypeDefinitionHandle(Helpers.GetValueLittleEndian(ptr, classSize)); + Interface = Helpers.FromTypeDefOrRefTag((uint)Helpers.GetValueLittleEndian(ptr.Slice(classSize, interfaceSize))); } } - unsafe struct InterfaceImplEntry + struct InterfaceImplEntry { readonly PEFile module; readonly MetadataReader metadata; @@ -120,7 +121,7 @@ public void OnInterfaceClick() string interfaceTooltip; public string InterfaceTooltip => GenerateTooltip(ref interfaceTooltip, module, interfaceImpl.Interface); - public InterfaceImplEntry(PEFile module, byte* ptr, int metadataOffset, int row) + public InterfaceImplEntry(PEFile module, ReadOnlySpan ptr, int metadataOffset, int row) { this.module = module; this.metadata = module.Metadata; @@ -128,7 +129,7 @@ public InterfaceImplEntry(PEFile module, byte* ptr, int metadataOffset, int row) var rowOffset = metadata.GetTableMetadataOffset(TableIndex.InterfaceImpl) + metadata.GetTableRowSize(TableIndex.InterfaceImpl) * (row - 1); this.Offset = metadataOffset + rowOffset; - this.interfaceImpl = new InterfaceImpl(ptr + rowOffset, metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4, metadata.ComputeCodedTokenSize(16384, TableMask.TypeDef | TableMask.TypeRef | TableMask.TypeSpec)); + this.interfaceImpl = new InterfaceImpl(ptr.Slice(rowOffset), metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4, metadata.ComputeCodedTokenSize(16384, TableMask.TypeDef | TableMask.TypeRef | TableMask.TypeSpec)); this.interfaceTooltip = null; this.classTooltip = null; } diff --git a/ILSpy/Metadata/CorTables/NestedClassTableTreeNode.cs b/ILSpy/Metadata/CorTables/NestedClassTableTreeNode.cs index de347fd332..acdcaad8f5 100644 --- a/ILSpy/Metadata/CorTables/NestedClassTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/NestedClassTableTreeNode.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; using System.Reflection.Metadata; using System.Reflection.Metadata.Ecma335; @@ -38,7 +39,7 @@ public NestedClassTableTreeNode(PEFile module) public override object Icon => Images.Literal; - public unsafe override bool View(ViewModels.TabPageModel tabPage) + public override bool View(ViewModels.TabPageModel tabPage) { tabPage.Title = Text.ToString(); tabPage.SupportsLanguageSwitching = false; @@ -50,7 +51,7 @@ public unsafe override bool View(ViewModels.TabPageModel tabPage) NestedClassEntry scrollTargetEntry = default; var length = metadata.GetTableRowCount(TableIndex.NestedClass); - byte* ptr = metadata.MetadataPointer; + ReadOnlySpan ptr = metadata.AsReadOnlySpan(); int metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; for (int rid = 1; rid <= length; rid++) { @@ -79,14 +80,14 @@ readonly struct NestedClass public readonly TypeDefinitionHandle Nested; public readonly TypeDefinitionHandle Enclosing; - public unsafe NestedClass(byte* ptr, int typeDefSize) + public NestedClass(ReadOnlySpan ptr, int typeDefSize) { - Nested = MetadataTokens.TypeDefinitionHandle(Helpers.GetValue(ptr, typeDefSize)); - Enclosing = MetadataTokens.TypeDefinitionHandle(Helpers.GetValue(ptr + typeDefSize, typeDefSize)); + Nested = MetadataTokens.TypeDefinitionHandle(Helpers.GetValueLittleEndian(ptr, typeDefSize)); + Enclosing = MetadataTokens.TypeDefinitionHandle(Helpers.GetValueLittleEndian(ptr.Slice(typeDefSize), typeDefSize)); } } - unsafe struct NestedClassEntry + struct NestedClassEntry { readonly PEFile module; readonly MetadataReader metadata; @@ -120,7 +121,7 @@ public void OnEnclosingClassClick() string enclosingClassTooltip; public string EnclosingClassTooltip => GenerateTooltip(ref enclosingClassTooltip, module, nestedClass.Enclosing); - public unsafe NestedClassEntry(PEFile module, byte* ptr, int metadataOffset, int row) + public NestedClassEntry(PEFile module, ReadOnlySpan ptr, int metadataOffset, int row) { this.module = module; this.metadata = module.Metadata; @@ -129,7 +130,7 @@ public unsafe NestedClassEntry(PEFile module, byte* ptr, int metadataOffset, int + metadata.GetTableRowSize(TableIndex.NestedClass) * (row - 1); this.Offset = metadataOffset + rowOffset; int typeDefSize = metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4; - this.nestedClass = new NestedClass(ptr + rowOffset, typeDefSize); + this.nestedClass = new NestedClass(ptr.Slice(rowOffset), typeDefSize); this.nestedClassTooltip = null; this.enclosingClassTooltip = null; } diff --git a/ILSpy/Metadata/CorTables/PropertyMapTableTreeNode.cs b/ILSpy/Metadata/CorTables/PropertyMapTableTreeNode.cs index 64d9bb19ad..d07b126c49 100644 --- a/ILSpy/Metadata/CorTables/PropertyMapTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/PropertyMapTableTreeNode.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; using System.Reflection.Metadata; using System.Reflection.Metadata.Ecma335; @@ -38,7 +39,7 @@ public PropertyMapTableTreeNode(PEFile module) public override object Icon => Images.Literal; - public unsafe override bool View(ViewModels.TabPageModel tabPage) + public override bool View(ViewModels.TabPageModel tabPage) { tabPage.Title = Text.ToString(); tabPage.SupportsLanguageSwitching = false; @@ -50,7 +51,7 @@ public unsafe override bool View(ViewModels.TabPageModel tabPage) PropertyMapEntry scrollTargetEntry = default; var length = metadata.GetTableRowCount(TableIndex.PropertyMap); - byte* ptr = metadata.MetadataPointer; + ReadOnlySpan ptr = metadata.AsReadOnlySpan(); int metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; for (int rid = 1; rid <= length; rid++) { @@ -79,14 +80,14 @@ readonly struct PropertyMap public readonly TypeDefinitionHandle Parent; public readonly PropertyDefinitionHandle PropertyList; - public unsafe PropertyMap(byte* ptr, int typeDefSize, int propertyDefSize) + public PropertyMap(ReadOnlySpan ptr, int typeDefSize, int propertyDefSize) { - Parent = MetadataTokens.TypeDefinitionHandle(Helpers.GetValue(ptr, typeDefSize)); - PropertyList = MetadataTokens.PropertyDefinitionHandle(Helpers.GetValue(ptr + typeDefSize, propertyDefSize)); + Parent = MetadataTokens.TypeDefinitionHandle(Helpers.GetValueLittleEndian(ptr, typeDefSize)); + PropertyList = MetadataTokens.PropertyDefinitionHandle(Helpers.GetValueLittleEndian(ptr.Slice(typeDefSize, propertyDefSize))); } } - unsafe struct PropertyMapEntry + struct PropertyMapEntry { readonly PEFile module; readonly MetadataReader metadata; @@ -120,7 +121,7 @@ public void OnPropertyListClick() string propertyListTooltip; public string PropertyListTooltip => GenerateTooltip(ref propertyListTooltip, module, propertyMap.PropertyList); - public PropertyMapEntry(PEFile module, byte* ptr, int metadataOffset, int row) + public PropertyMapEntry(PEFile module, ReadOnlySpan ptr, int metadataOffset, int row) { this.module = module; this.metadata = module.Metadata; @@ -130,7 +131,7 @@ public PropertyMapEntry(PEFile module, byte* ptr, int metadataOffset, int row) this.Offset = metadataOffset + rowOffset; int typeDefSize = metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4; int propertyDefSize = metadata.GetTableRowCount(TableIndex.Property) < ushort.MaxValue ? 2 : 4; - this.propertyMap = new PropertyMap(ptr + rowOffset, typeDefSize, propertyDefSize); + this.propertyMap = new PropertyMap(ptr.Slice(rowOffset), typeDefSize, propertyDefSize); this.propertyListTooltip = null; this.parentTooltip = null; } diff --git a/ILSpy/Metadata/DebugTables/CustomDebugInformationTableTreeNode.cs b/ILSpy/Metadata/DebugTables/CustomDebugInformationTableTreeNode.cs index 9e9d46c612..420232cafe 100644 --- a/ILSpy/Metadata/DebugTables/CustomDebugInformationTableTreeNode.cs +++ b/ILSpy/Metadata/DebugTables/CustomDebugInformationTableTreeNode.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team // // 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 @@ -141,11 +141,11 @@ static CustomDebugInformationKind GetKind(MetadataReader metadata, GuidHandle h) } if (KnownGuids.DynamicLocalVariables == guid) { - return CustomDebugInformationKind.StateMachineHoistedLocalScopes; + return CustomDebugInformationKind.DynamicLocalVariables; } if (KnownGuids.DefaultNamespaces == guid) { - return CustomDebugInformationKind.StateMachineHoistedLocalScopes; + return CustomDebugInformationKind.DefaultNamespaces; } if (KnownGuids.EditAndContinueLocalSlotMap == guid) { @@ -341,4 +341,4 @@ public override void Decompile(Language language, ITextOutput output, Decompilat language.WriteCommentLine(output, "CustomDebugInformation"); } } -} \ No newline at end of file +} diff --git a/ILSpy/Metadata/DebugTables/StateMachineMethodTableTreeNode.cs b/ILSpy/Metadata/DebugTables/StateMachineMethodTableTreeNode.cs index e93c0c3d9a..f4a463e78d 100644 --- a/ILSpy/Metadata/DebugTables/StateMachineMethodTableTreeNode.cs +++ b/ILSpy/Metadata/DebugTables/StateMachineMethodTableTreeNode.cs @@ -44,7 +44,7 @@ public StateMachineMethodTableTreeNode(PEFile module, MetadataReader metadata, b public override object Icon => Images.Literal; - public unsafe override bool View(ViewModels.TabPageModel tabPage) + public override bool View(ViewModels.TabPageModel tabPage) { tabPage.Title = Text.ToString(); tabPage.SupportsLanguageSwitching = false; @@ -53,7 +53,7 @@ public unsafe override bool View(ViewModels.TabPageModel tabPage) var list = new List(); StateMachineMethodEntry scrollTargetEntry = default; var length = metadata.GetTableRowCount(TableIndex.StateMachineMethod); - var reader = new BlobReader(metadata.MetadataPointer, metadata.MetadataLength); + var reader = metadata.AsBlobReader(); reader.Offset = metadata.GetTableMetadataOffset(TableIndex.StateMachineMethod); for (int rid = 1; rid <= length; rid++) diff --git a/ILSpy/Metadata/Helpers.cs b/ILSpy/Metadata/Helpers.cs index da418b554a..792b73e1f4 100644 --- a/ILSpy/Metadata/Helpers.cs +++ b/ILSpy/Metadata/Helpers.cs @@ -212,11 +212,20 @@ static void ApplyAttributes(PropertyDescriptor descriptor, Binding binding, Data } } + [Obsolete("Use safe GetValueLittleEndian(ReadOnlySpan) or appropriate BinaryPrimitives.Read* method")] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe int GetValue(byte* ptr, int size) + => GetValueLittleEndian(new ReadOnlySpan(ptr, size)); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int GetValueLittleEndian(ReadOnlySpan ptr, int size) + => GetValueLittleEndian(ptr.Slice(0, size)); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int GetValueLittleEndian(ReadOnlySpan ptr) { int result = 0; - for (int i = 0; i < size; i += 2) + for (int i = 0; i < ptr.Length; i += 2) { result |= ptr[i] << 8 * i; result |= ptr[i + 1] << 8 * (i + 1); diff --git a/ILSpy/Properties/Resources.Designer.cs b/ILSpy/Properties/Resources.Designer.cs index 397e5da3a7..07d6d8832b 100644 --- a/ILSpy/Properties/Resources.Designer.cs +++ b/ILSpy/Properties/Resources.Designer.cs @@ -495,6 +495,15 @@ public static string CheckUpdates { } } + /// + /// Looks up a localized string similar to Clear assembly list. + /// + public static string ClearAssemblyList { + get { + return ResourceManager.GetString("ClearAssemblyList", resourceCulture); + } + } + /// /// Looks up a localized string similar to Close. /// diff --git a/ILSpy/Properties/Resources.resx b/ILSpy/Properties/Resources.resx index 6623f03530..e7bc5c4e7a 100644 --- a/ILSpy/Properties/Resources.resx +++ b/ILSpy/Properties/Resources.resx @@ -186,6 +186,9 @@ Are you sure you want to continue? Checking... + + Clear assembly list + Close diff --git a/ILSpy/TextView/OutputLengthExceededException.cs b/ILSpy/TextView/OutputLengthExceededException.cs index 95fd26e388..5e1f592d5f 100644 --- a/ILSpy/TextView/OutputLengthExceededException.cs +++ b/ILSpy/TextView/OutputLengthExceededException.cs @@ -17,14 +17,13 @@ // DEALINGS IN THE SOFTWARE. using System; -using System.Runtime.Serialization; namespace ICSharpCode.ILSpy.TextView { /// /// This exception gets used when the text output is longer than the specified limit. /// - class OutputLengthExceededException : Exception, ISerializable + class OutputLengthExceededException : Exception { public OutputLengthExceededException() { @@ -37,10 +36,5 @@ public OutputLengthExceededException(string message) : base(message) public OutputLengthExceededException(string message, Exception innerException) : base(message, innerException) { } - - // This constructor is needed for serialization. - protected OutputLengthExceededException(SerializationInfo info, StreamingContext context) : base(info, context) - { - } } } \ No newline at end of file diff --git a/ILSpy/ViewModels/ManageAssemblyListsViewModel.cs b/ILSpy/ViewModels/ManageAssemblyListsViewModel.cs index 4bca507f23..57f6edb96e 100644 --- a/ILSpy/ViewModels/ManageAssemblyListsViewModel.cs +++ b/ILSpy/ViewModels/ManageAssemblyListsViewModel.cs @@ -71,7 +71,7 @@ IEnumerable ResolvePreconfiguredAssemblyLists() continue; foreach (var versionDir in Directory.GetDirectories(sdkDir)) { - var match = Regex.Match(versionDir, @"[/\\](?[A-z0-9.]+)[/\\](?\d+\.\d)+(.(?\d+))?(?-preview.*)?$"); + var match = Regex.Match(versionDir, @"[/\\](?[A-z0-9.]+)[/\\](?\d+\.\d+)(.(?\d+))?(?-.*)?$"); if (!match.Success) continue; string name = match.Groups["name"].Value; diff --git a/NuGet.config b/NuGet.config index 40b60b1652..5209a02bfd 100644 --- a/NuGet.config +++ b/NuGet.config @@ -1,8 +1,23 @@  - + + + + + + + + + + + + + + + + diff --git a/README.md b/README.md index 9db6276d51..adb3b2c8e7 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Decompiler Frontends Aside from the WPF UI ILSpy (downloadable via Releases, see also [plugins](https://github.com/icsharpcode/ILSpy/wiki/Plugins)), the following other frontends are available: -* Visual Studio 2022 ships with decompilation support for F12 enabled by default (using our engine v7.1). +* Visual Studio 2022 ships with decompilation support for F12 enabled by default (using our engine v8.1). * In Visual Studio 2019, you have to manually enable F12 support. Go to Tools / Options / Text Editor / C# / Advanced and check "Enable navigation to decompiled source" * [C# for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csharp) ships with decompilation support as well. To enable, activate the setting "Enable Decompilation Support". * Our Visual Studio 2022 extension [marketplace](https://marketplace.visualstudio.com/items?itemName=SharpDevelopTeam.ILSpy2022) @@ -48,11 +48,11 @@ How to build - Make sure PowerShell (at least version) 5.0 is installed. - Clone the ILSpy repository using git. - Execute `git submodule update --init --recursive` to download the ILSpy-Tests submodule (used by some test cases). -- Install Visual Studio (documented version: 17.1). You can install the necessary components in one of 3 ways: +- Install Visual Studio (documented version: 17.8). You can install the necessary components in one of 3 ways: - Follow Microsoft's instructions for [importing a configuration](https://docs.microsoft.com/en-us/visualstudio/install/import-export-installation-configurations?view=vs-2022#import-a-configuration), and import the .vsconfig file located at the root of the solution. - Alternatively, you can open the ILSpy solution (ILSpy.sln) and Visual Studio will [prompt you to install the missing components](https://docs.microsoft.com/en-us/visualstudio/install/import-export-installation-configurations?view=vs-2022#automatically-install-missing-components). - Finally, you can manually install the necessary components via the Visual Studio Installer. The workloads/components are as follows: - - Workload ".NET Desktop Development". This workload includes the .NET Framework 4.8 SDK and the .NET Framework 4.7.2 targeting pack, as well as the [.NET 6.0 SDK](https://dotnet.microsoft.com/download/dotnet/6.0) and [.NET 7.0 SDK](https://dotnet.microsoft.com/download/dotnet/7.0) (ILSpy.csproj targets .NET 6.0, but we have net472+net70 projects too). _Note: The optional components of this workload are not required for ILSpy_ + - Workload ".NET Desktop Development". This workload includes the .NET Framework 4.8 SDK and the .NET Framework 4.7.2 targeting pack, as well as the [.NET 8.0 SDK](https://dotnet.microsoft.com/download/dotnet/8.0) (ILSpy.csproj targets .NET 6.0, but we have net472 projects too). _Note: The optional components of this workload are not required for ILSpy_ - Workload "Visual Studio extension development" (ILSpy.sln contains a VS extension project) _Note: The optional components of this workload are not required for ILSpy_ - Individual Component "MSVC v143 - VS 2022 C++ x64/x86 build tools" (or similar) - _The VC++ toolset is optional_; if present it is used for `editbin.exe` to modify the stack size used by ILSpy.exe from 1MB to 16MB, because the decompiler makes heavy use of recursion, where small stack sizes lead to problems in very complex methods. @@ -71,7 +71,7 @@ If this problem occurs, please manually install the .NET 6.0 SDK from [here](htt #### Unix / Mac: -- Make sure [.NET 7.0 SDK](https://dotnet.microsoft.com/download/dotnet/7.0) is installed. +- Make sure [.NET 8.0 SDK](https://dotnet.microsoft.com/download/dotnet/8.0) is installed. - Make sure [PowerShell](https://github.com/PowerShell/PowerShell) is installed (formerly known as PowerShell Core) - Clone the repository using git. - Execute `git submodule update --init --recursive` to download the ILSpy-Tests submodule (used by some test cases). diff --git a/SharpTreeView/ICSharpCode.TreeView.csproj b/SharpTreeView/ICSharpCode.TreeView.csproj index 2929c0b301..a0b1c2b99e 100644 --- a/SharpTreeView/ICSharpCode.TreeView.csproj +++ b/SharpTreeView/ICSharpCode.TreeView.csproj @@ -5,7 +5,7 @@ true False True - net6.0-windows + net8.0-windows ..\ICSharpCode.Decompiler\ICSharpCode.Decompiler.snk true @@ -20,10 +20,8 @@ true - - - + diff --git a/TestPlugin/TestPlugin.csproj b/TestPlugin/TestPlugin.csproj index 5ff29f0b23..50d7dadba6 100644 --- a/TestPlugin/TestPlugin.csproj +++ b/TestPlugin/TestPlugin.csproj @@ -1,7 +1,7 @@  - net6.0-windows + net8.0-windows Test.Plugin true true diff --git a/global.json b/global.json index 1fcfe4feea..6a5d4badd3 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "7.0.100", + "version": "8.0.100", "rollForward": "major", "allowPrerelease": true } diff --git a/packages.props b/packages.props deleted file mode 100644 index 236f7b6617..0000000000 --- a/packages.props +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - 7.0.0 - 7.0.0 - 6.0.0 - 6.0.0 - - 1.1.0-beta2-22171-02 - 0.11.4 - 6.3.0.90 - 2.8.7 - - - - 3.13.3 - 4.4.2 - 3.0.124 - 3.2.0 - 17.5.0 - 2017.7.26.1241 - - 4.6.0 - - 7.0.0 - - 7.0.0 - - diff --git a/publish.ps1 b/publish.ps1 index c2be01b3dc..6854d2f93a 100644 --- a/publish.ps1 +++ b/publish.ps1 @@ -1,6 +1,6 @@ -$output_arm64 = "./ILSpy/bin/Release/net6.0-windows/win-arm64/publish/fwdependent" -$output_x64 = "./ILSpy/bin/Release/net6.0-windows/win-x64/publish/fwdependent" -$output_x64_selfcontained = "./ILSpy/bin/Release/net6.0-windows/win-x64/publish/selfcontained" +$output_arm64 = "./ILSpy/bin/Release/net8.0-windows/win-arm64/publish/fwdependent" +$output_x64 = "./ILSpy/bin/Release/net8.0-windows/win-x64/publish/fwdependent" +$output_x64_selfcontained = "./ILSpy/bin/Release/net8.0-windows/win-x64/publish/selfcontained" dotnet publish ./ILSpy/ILSpy.csproj -c Release --no-restore --no-self-contained -r win-arm64 -o $output_arm64 dotnet publish ./ILSpy.ReadyToRun/ILSpy.ReadyToRun.csproj -c Release --no-restore --no-self-contained -r win-arm64 -o $output_arm64