Browse Source

Fix #1699: Auto properties without getter are not properly decompiled

Also fixes wrong decompilation of auto properties modified by Fody.
pull/1738/head
Siegfried Pammer 6 years ago
parent
commit
941906e8db
  1. 2
      ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs
  2. 37
      ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs
  3. 5
      ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs

2
ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs

@ -1522,7 +1522,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -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()));

37
ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs

@ -98,7 +98,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -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 @@ -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 @@ -652,14 +667,12 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
var parent = identifier.Parent;
var mrr = parent.Annotation<MemberResolveResult>();
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<MemberResolveResult>();
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<MemberResolveResult>();
parent.AddAnnotation(new MemberResolveResult(mrr.TargetResult, property));
return Identifier.Create(property.Name);
}
}
return null;
@ -673,7 +686,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -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<MemberResolveResult>();
parent.AddAnnotation(new MemberResolveResult(mrr.TargetResult, @event));
return identifier;

5
ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs

@ -281,6 +281,11 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -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
/// <summary>
/// Gets all type definitions in the compilation.

Loading…
Cancel
Save