From 69fdc55b419e4f99020af2f068f3a3a44b06dfe2 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 12 May 2018 00:16:07 +0200 Subject: [PATCH] =?UTF-8?q?Add=20support=20for=20C#=207.3=20Attributes=20o?= =?UTF-8?q?n=20backing=20fields:=20Allows=20[field:=20=E2=80=A6]=20attribu?= =?UTF-8?q?tes=20on=20an=20auto-implemented=20property=20to=20target=20its?= =?UTF-8?q?=20backing=20field.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TestCases/Pretty/AutoProperties.cs | 11 ++++++- .../Pretty/AutoProperties.opt.roslyn.il | 32 ++++++++++++++++++ .../TestCases/Pretty/AutoProperties.roslyn.il | 33 +++++++++++++++++++ .../Transforms/PatternStatementTransform.cs | 16 +++++++++ 4 files changed, 91 insertions(+), 1 deletion(-) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/AutoProperties.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/AutoProperties.cs index 9c069c520..6e2b5a74d 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/AutoProperties.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/AutoProperties.cs @@ -1,4 +1,6 @@ -namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty +using System; + +namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty { // TODO : maybe use single-line formatting in this case? internal class AutoProperties @@ -20,5 +22,12 @@ get; set; } = 4; + + [Obsolete("Property")] + [field: Obsolete("Field")] + public int PropertyWithAttributeOnBackingField { + get; + set; + } } } diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/AutoProperties.opt.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/AutoProperties.opt.roslyn.il index e9c2f5355..2cbd82acc 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/AutoProperties.opt.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/AutoProperties.opt.roslyn.il @@ -44,6 +44,9 @@ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .field private static int32 'k__BackingField' .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field private int32 'k__BackingField' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.ObsoleteAttribute::.ctor(string) = ( 01 00 05 46 69 65 6C 64 00 00 ) // ...Field.. .method public hidebysig specialname instance int32 get_A() cil managed { @@ -109,6 +112,29 @@ IL_0006: ret } // end of method AutoProperties::set_D + .method public hidebysig specialname instance int32 + get_PropertyWithAttributeOnBackingField() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.AutoProperties::'k__BackingField' + IL_0006: ret + } // end of method AutoProperties::get_PropertyWithAttributeOnBackingField + + .method public hidebysig specialname instance void + set_PropertyWithAttributeOnBackingField(int32 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.AutoProperties::'k__BackingField' + IL_0007: ret + } // end of method AutoProperties::set_PropertyWithAttributeOnBackingField + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { @@ -155,6 +181,12 @@ .get int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.AutoProperties::get_D() .set void ICSharpCode.Decompiler.Tests.TestCases.Pretty.AutoProperties::set_D(int32) } // end of property AutoProperties::D + .property instance int32 PropertyWithAttributeOnBackingField() + { + .custom instance void [mscorlib]System.ObsoleteAttribute::.ctor(string) = ( 01 00 08 50 72 6F 70 65 72 74 79 00 00 ) // ...Property.. + .get instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.AutoProperties::get_PropertyWithAttributeOnBackingField() + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.AutoProperties::set_PropertyWithAttributeOnBackingField(int32) + } // end of property AutoProperties::PropertyWithAttributeOnBackingField } // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.AutoProperties diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/AutoProperties.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/AutoProperties.roslyn.il index 4e0e357d5..1fec1b71f 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/AutoProperties.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/AutoProperties.roslyn.il @@ -48,6 +48,10 @@ .field private static int32 'k__BackingField' .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .field private int32 'k__BackingField' + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.ObsoleteAttribute::.ctor(string) = ( 01 00 05 46 69 65 6C 64 00 00 ) // ...Field.. .method public hidebysig specialname instance int32 get_A() cil managed { @@ -113,6 +117,29 @@ IL_0006: ret } // end of method AutoProperties::set_D + .method public hidebysig specialname instance int32 + get_PropertyWithAttributeOnBackingField() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.AutoProperties::'k__BackingField' + IL_0006: ret + } // end of method AutoProperties::get_PropertyWithAttributeOnBackingField + + .method public hidebysig specialname instance void + set_PropertyWithAttributeOnBackingField(int32 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.AutoProperties::'k__BackingField' + IL_0007: ret + } // end of method AutoProperties::set_PropertyWithAttributeOnBackingField + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { @@ -160,6 +187,12 @@ .get int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.AutoProperties::get_D() .set void ICSharpCode.Decompiler.Tests.TestCases.Pretty.AutoProperties::set_D(int32) } // end of property AutoProperties::D + .property instance int32 PropertyWithAttributeOnBackingField() + { + .custom instance void [mscorlib]System.ObsoleteAttribute::.ctor(string) = ( 01 00 08 50 72 6F 70 65 72 74 79 00 00 ) // ...Property.. + .get instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.AutoProperties::get_PropertyWithAttributeOnBackingField() + .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.AutoProperties::set_PropertyWithAttributeOnBackingField(int32) + } // end of property AutoProperties::PropertyWithAttributeOnBackingField } // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.AutoProperties diff --git a/ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs b/ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs index 4a1967d2e..97f97395f 100644 --- a/ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs +++ b/ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs @@ -510,6 +510,17 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms property.Getter.Body = null; property.Setter.Body = null; } + // Add C# 7.3 attributes on backing field: + var attributes = fieldInfo.Attributes + .Where(a => !attributeTypesToRemoveFromAutoProperties.Any(t => t == a.AttributeType.FullName)) + .Select(context.TypeSystemAstBuilder.ConvertAttribute).ToArray(); + if (attributes.Length > 0) { + var section = new AttributeSection { + AttributeTarget = "field" + }; + section.Attributes.AddRange(attributes); + property.Attributes.Add(section); + } // Since the property instance is not changed, we can continue in the visitor as usual, so return null return null; } @@ -706,6 +717,11 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms "System.Runtime.CompilerServices.MethodImplAttribute" }; + static readonly string[] attributeTypesToRemoveFromAutoProperties = new[] { + "System.Runtime.CompilerServices.CompilerGeneratedAttribute", + "System.Diagnostics.DebuggerBrowsableAttribute" + }; + bool CheckAutomaticEventV4(CustomEventDeclaration ev, out Match addMatch, out Match removeMatch) { addMatch = removeMatch = default(Match);