diff --git a/ICSharpCode.Decompiler.Tests/DecompilerTestBase.cs b/ICSharpCode.Decompiler.Tests/DecompilerTestBase.cs index 959ede722..ba79100e1 100644 --- a/ICSharpCode.Decompiler.Tests/DecompilerTestBase.cs +++ b/ICSharpCode.Decompiler.Tests/DecompilerTestBase.cs @@ -54,6 +54,7 @@ namespace ICSharpCode.Decompiler.Tests CSharpDecompiler decompiler = new CSharpDecompiler(assembly.MainModule, new DecompilerSettings()); + decompiler.AstTransforms.Insert(0, new RemoveEmbeddedAtttributes()); decompiler.AstTransforms.Insert(0, new RemoveCompilerAttribute()); var syntaxTree = decompiler.DecompileWholeModuleAsSingleFile(); diff --git a/ICSharpCode.Decompiler.Tests/Helpers/RemoveCompilerAttribute.cs b/ICSharpCode.Decompiler.Tests/Helpers/RemoveCompilerAttribute.cs index 34f54526a..3e71a38b7 100644 --- a/ICSharpCode.Decompiler.Tests/Helpers/RemoveCompilerAttribute.cs +++ b/ICSharpCode.Decompiler.Tests/Helpers/RemoveCompilerAttribute.cs @@ -1,5 +1,8 @@ -using ICSharpCode.Decompiler.CSharp.Syntax; +using System.Collections.Generic; +using ICSharpCode.Decompiler.CSharp; +using ICSharpCode.Decompiler.CSharp.Syntax; using ICSharpCode.Decompiler.CSharp.Transforms; +using ICSharpCode.Decompiler.TypeSystem; namespace ICSharpCode.Decompiler.Tests.Helpers { @@ -30,4 +33,30 @@ namespace ICSharpCode.Decompiler.Tests.Helpers rootNode.AcceptVisitor(this, null); } } + + public class RemoveEmbeddedAtttributes : DepthFirstAstVisitor, IAstTransform + { + HashSet attributeNames = new HashSet() { + "System.Runtime.CompilerServices.IsReadOnlyAttribute", + "System.Runtime.CompilerServices.IsByRefLikeAttribute", + "Microsoft.CodeAnalysis.EmbeddedAttribute", + }; + + public override object VisitTypeDeclaration(TypeDeclaration typeDeclaration, object data) + { + var typeDefinition = typeDeclaration.GetSymbol() as ITypeDefinition; + if (typeDefinition == null || !attributeNames.Contains(typeDefinition.FullName)) + return null; + if (typeDeclaration.Parent is NamespaceDeclaration ns && ns.Members.Count == 1) + ns.Remove(); + else + typeDeclaration.Remove(); + return null; + } + + public void Run(AstNode rootNode, TransformContext context) + { + rootNode.AcceptVisitor(this, null); + } + } } diff --git a/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs b/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs index 9ec97b6f7..827398c35 100644 --- a/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs +++ b/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs @@ -364,6 +364,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers using (var module = ModuleDefinition.ReadModule(assemblyFileName)) { var typeSystem = new DecompilerTypeSystem(module); CSharpDecompiler decompiler = new CSharpDecompiler(typeSystem, settings ?? new DecompilerSettings()); + decompiler.AstTransforms.Insert(0, new RemoveEmbeddedAtttributes()); decompiler.AstTransforms.Insert(0, new RemoveCompilerAttribute()); decompiler.AstTransforms.Add(new EscapeInvalidIdentifiers()); var syntaxTree = decompiler.DecompileWholeModuleAsSingleFile(); diff --git a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj index 2977e1f54..b5ed3d1dd 100644 --- a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj +++ b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj @@ -64,6 +64,7 @@ + diff --git a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs index 7c8d041ed..0f7e227c9 100644 --- a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs @@ -261,6 +261,12 @@ namespace ICSharpCode.Decompiler.Tests Run(cscOptions: cscOptions); } + [Test] + public void RefLocalsAndReturns([ValueSource("roslynOnlyOptions")] CSharpCompilerOptions cscOptions) + { + RunForLibrary(cscOptions: cscOptions); + } + void RunForLibrary([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CSharpCompilerOptions cscOptions = CSharpCompilerOptions.None, DecompilerSettings decompilerSettings = null) { Run(testName, asmOptions | AssemblerOptions.Library, cscOptions | CSharpCompilerOptions.Library, decompilerSettings); diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/RefLocalsAndReturns.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/RefLocalsAndReturns.cs new file mode 100644 index 000000000..91f83ffa0 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/RefLocalsAndReturns.cs @@ -0,0 +1,15 @@ +namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty +{ + internal class RefLocalsAndReturns + { + public ref struct RefStruct + { + private int dummy; + } + + public readonly ref struct ReadOnlyRefStruct + { + private readonly int dummy; + } + } +} diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/RefLocalsAndReturns.opt.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/RefLocalsAndReturns.opt.roslyn.il new file mode 100644 index 000000000..3d3a2cf99 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/RefLocalsAndReturns.opt.roslyn.il @@ -0,0 +1,138 @@ + +// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Copyright (c) Microsoft Corporation. All rights reserved. + + + +// Metadata version: v4.0.30319 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 4:0:0:0 +} +.assembly RefLocalsAndReturns +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx + 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows. + + // --- The following custom attribute is added automatically, do not uncomment ------- + // .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 ) + + .permissionset reqmin + = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}} + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module RefLocalsAndReturns.dll +// MVID: {88B7B033-A21B-4EB3-8D45-FFCD0934C008} +.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) +.imagebase 0x10000000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000001 // ILONLY +// Image base: 0x03430000 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class private auto ansi sealed beforefieldinit Microsoft.CodeAnalysis.EmbeddedAttribute + extends [mscorlib]System.Attribute +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void Microsoft.CodeAnalysis.EmbeddedAttribute::.ctor() = ( 01 00 00 00 ) + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Attribute::.ctor() + IL_0006: ret + } // end of method EmbeddedAttribute::.ctor + +} // end of class Microsoft.CodeAnalysis.EmbeddedAttribute + +.class private auto ansi sealed beforefieldinit System.Runtime.CompilerServices.IsReadOnlyAttribute + extends [mscorlib]System.Attribute +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void Microsoft.CodeAnalysis.EmbeddedAttribute::.ctor() = ( 01 00 00 00 ) + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Attribute::.ctor() + IL_0006: ret + } // end of method IsReadOnlyAttribute::.ctor + +} // end of class System.Runtime.CompilerServices.IsReadOnlyAttribute + +.class private auto ansi sealed beforefieldinit System.Runtime.CompilerServices.IsByRefLikeAttribute + extends [mscorlib]System.Attribute +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void Microsoft.CodeAnalysis.EmbeddedAttribute::.ctor() = ( 01 00 00 00 ) + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Attribute::.ctor() + IL_0006: ret + } // end of method IsByRefLikeAttribute::.ctor + +} // end of class System.Runtime.CompilerServices.IsByRefLikeAttribute + +.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.RefLocalsAndReturns + extends [mscorlib]System.Object +{ + .class sequential ansi sealed nested public beforefieldinit RefStruct + extends [mscorlib]System.ValueType + { + .custom instance void System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.ObsoleteAttribute::.ctor(string, + bool) = ( 01 00 52 54 79 70 65 73 20 77 69 74 68 20 65 6D // ..RTypes with em + 62 65 64 64 65 64 20 72 65 66 65 72 65 6E 63 65 // bedded reference + 73 20 61 72 65 20 6E 6F 74 20 73 75 70 70 6F 72 // s are not suppor + 74 65 64 20 69 6E 20 74 68 69 73 20 76 65 72 73 // ted in this vers + 69 6F 6E 20 6F 66 20 79 6F 75 72 20 63 6F 6D 70 // ion of your comp + 69 6C 65 72 2E 01 00 00 ) // iler.... + .field private int32 dummy + } // end of class RefStruct + + .class sequential ansi sealed nested public beforefieldinit ReadOnlyRefStruct + extends [mscorlib]System.ValueType + { + .custom instance void System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.ObsoleteAttribute::.ctor(string, + bool) = ( 01 00 52 54 79 70 65 73 20 77 69 74 68 20 65 6D // ..RTypes with em + 62 65 64 64 65 64 20 72 65 66 65 72 65 6E 63 65 // bedded reference + 73 20 61 72 65 20 6E 6F 74 20 73 75 70 70 6F 72 // s are not suppor + 74 65 64 20 69 6E 20 74 68 69 73 20 76 65 72 73 // ted in this vers + 69 6F 6E 20 6F 66 20 79 6F 75 72 20 63 6F 6D 70 // ion of your comp + 69 6C 65 72 2E 01 00 00 ) // iler.... + .custom instance void System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 ) + .field private initonly int32 dummy + } // end of class ReadOnlyRefStruct + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method RefLocalsAndReturns::.ctor + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.RefLocalsAndReturns + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/RefLocalsAndReturns.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/RefLocalsAndReturns.roslyn.il new file mode 100644 index 000000000..207ce2244 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/RefLocalsAndReturns.roslyn.il @@ -0,0 +1,142 @@ + +// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Copyright (c) Microsoft Corporation. All rights reserved. + + + +// Metadata version: v4.0.30319 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 4:0:0:0 +} +.assembly RefLocalsAndReturns +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx + 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows. + + // --- The following custom attribute is added automatically, do not uncomment ------- + // .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 ) + + .permissionset reqmin + = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}} + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module RefLocalsAndReturns.dll +// MVID: {20DB058A-C93C-4686-AE13-1EA32F00D299} +.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) +.imagebase 0x10000000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000001 // ILONLY +// Image base: 0x035D0000 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class private auto ansi sealed beforefieldinit Microsoft.CodeAnalysis.EmbeddedAttribute + extends [mscorlib]System.Attribute +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void Microsoft.CodeAnalysis.EmbeddedAttribute::.ctor() = ( 01 00 00 00 ) + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Attribute::.ctor() + IL_0006: nop + IL_0007: ret + } // end of method EmbeddedAttribute::.ctor + +} // end of class Microsoft.CodeAnalysis.EmbeddedAttribute + +.class private auto ansi sealed beforefieldinit System.Runtime.CompilerServices.IsReadOnlyAttribute + extends [mscorlib]System.Attribute +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void Microsoft.CodeAnalysis.EmbeddedAttribute::.ctor() = ( 01 00 00 00 ) + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Attribute::.ctor() + IL_0006: nop + IL_0007: ret + } // end of method IsReadOnlyAttribute::.ctor + +} // end of class System.Runtime.CompilerServices.IsReadOnlyAttribute + +.class private auto ansi sealed beforefieldinit System.Runtime.CompilerServices.IsByRefLikeAttribute + extends [mscorlib]System.Attribute +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void Microsoft.CodeAnalysis.EmbeddedAttribute::.ctor() = ( 01 00 00 00 ) + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Attribute::.ctor() + IL_0006: nop + IL_0007: ret + } // end of method IsByRefLikeAttribute::.ctor + +} // end of class System.Runtime.CompilerServices.IsByRefLikeAttribute + +.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.RefLocalsAndReturns + extends [mscorlib]System.Object +{ + .class sequential ansi sealed nested public beforefieldinit RefStruct + extends [mscorlib]System.ValueType + { + .custom instance void System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.ObsoleteAttribute::.ctor(string, + bool) = ( 01 00 52 54 79 70 65 73 20 77 69 74 68 20 65 6D // ..RTypes with em + 62 65 64 64 65 64 20 72 65 66 65 72 65 6E 63 65 // bedded reference + 73 20 61 72 65 20 6E 6F 74 20 73 75 70 70 6F 72 // s are not suppor + 74 65 64 20 69 6E 20 74 68 69 73 20 76 65 72 73 // ted in this vers + 69 6F 6E 20 6F 66 20 79 6F 75 72 20 63 6F 6D 70 // ion of your comp + 69 6C 65 72 2E 01 00 00 ) // iler.... + .field private int32 dummy + } // end of class RefStruct + + .class sequential ansi sealed nested public beforefieldinit ReadOnlyRefStruct + extends [mscorlib]System.ValueType + { + .custom instance void System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.ObsoleteAttribute::.ctor(string, + bool) = ( 01 00 52 54 79 70 65 73 20 77 69 74 68 20 65 6D // ..RTypes with em + 62 65 64 64 65 64 20 72 65 66 65 72 65 6E 63 65 // bedded reference + 73 20 61 72 65 20 6E 6F 74 20 73 75 70 70 6F 72 // s are not suppor + 74 65 64 20 69 6E 20 74 68 69 73 20 76 65 72 73 // ted in this vers + 69 6F 6E 20 6F 66 20 79 6F 75 72 20 63 6F 6D 70 // ion of your comp + 69 6C 65 72 2E 01 00 00 ) // iler.... + .custom instance void System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 ) + .field private initonly int32 dummy + } // end of class ReadOnlyRefStruct + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // 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 RefLocalsAndReturns::.ctor + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.RefLocalsAndReturns + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE ***********************