diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs b/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs index 64d677fb4..f67d60321 100644 --- a/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs @@ -1522,7 +1522,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax Accessor decl = new Accessor(); if (this.ShowAccessibility && accessor.Accessibility != ownerAccessibility) decl.Modifiers = ModifierFromAccessibility(accessor.Accessibility); - if (accessor.ThisIsRefReadOnly && accessor.DeclaringTypeDefinition?.IsReadOnly == false) + if (accessor.HasReadonlyModifier()) decl.Modifiers |= Modifiers.Readonly; if (ShowAttributes) { decl.Attributes.AddRange(ConvertAttributes(accessor.GetAttributes())); diff --git a/ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs b/ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs index 8692bf678..b4758059d 100644 --- a/ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs +++ b/ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs @@ -98,7 +98,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms public override AstNode VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration) { if (context.Settings.AutomaticProperties) { - AstNode result = TransformAutomaticProperties(propertyDeclaration); + AstNode result = TransformAutomaticProperty(propertyDeclaration); if (result != null) return result; } @@ -554,10 +554,25 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms } }; - PropertyDeclaration TransformAutomaticProperties(PropertyDeclaration propertyDeclaration) + bool CanTransformToAutomaticProperty(IProperty property) + { + if (!property.CanGet) + return false; + if (!property.Getter.IsCompilerGenerated()) + return false; + if (property.Setter is IMethod setter) { + if (!setter.IsCompilerGenerated()) + return false; + if (setter.HasReadonlyModifier()) + return false; + } + return true; + } + + PropertyDeclaration TransformAutomaticProperty(PropertyDeclaration propertyDeclaration) { IProperty property = propertyDeclaration.GetSymbol() as IProperty; - if (!property.CanGet || (!property.Getter.IsCompilerGenerated() && (property.Setter?.IsCompilerGenerated() == false))) + if (!CanTransformToAutomaticProperty(property)) return null; IField field = null; Match m = automaticPropertyPattern.Match(propertyDeclaration); @@ -652,14 +667,12 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms var parent = identifier.Parent; var mrr = parent.Annotation(); var field = mrr?.Member as IField; - if (field != null && field.IsCompilerGenerated()) { - var propertyName = identifier.Name.Substring(1, identifier.Name.Length - 1 - ">k__BackingField".Length); - var property = field.DeclaringTypeDefinition.GetProperties(p => p.Name == propertyName, GetMemberOptions.IgnoreInheritedMembers).FirstOrDefault(); - if (property != null) { - parent.RemoveAnnotations(); - parent.AddAnnotation(new MemberResolveResult(mrr.TargetResult, property)); - return Identifier.Create(propertyName); - } + if (field != null && IsBackingFieldOfAutomaticProperty(field, out var property) + && CanTransformToAutomaticProperty(property) && currentMethod.AccessorOwner != property) + { + parent.RemoveAnnotations(); + parent.AddAnnotation(new MemberResolveResult(mrr.TargetResult, property)); + return Identifier.Create(property.Name); } } return null; @@ -673,7 +686,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms if (field == null) return null; var @event = field.DeclaringType.GetEvents(ev => ev.Name == field.Name, GetMemberOptions.IgnoreInheritedMembers).SingleOrDefault(); - if (@event != null) { + if (@event != null && currentMethod.AccessorOwner != @event) { parent.RemoveAnnotations(); parent.AddAnnotation(new MemberResolveResult(mrr.TargetResult, @event)); return identifier; diff --git a/ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs b/ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs index 78c5a1892..1b6e6cdbe 100644 --- a/ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs +++ b/ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs @@ -281,6 +281,11 @@ namespace ICSharpCode.Decompiler.TypeSystem return ty; } + public static bool HasReadonlyModifier(this IMethod accessor) + { + return accessor.ThisIsRefReadOnly && accessor.DeclaringTypeDefinition?.IsReadOnly == false; + } + #region GetType/Member /// /// Gets all type definitions in the compilation.