Browse Source

Add support for read-only auto properties

pull/734/merge
Siegfried Pammer 8 years ago
parent
commit
c9010a5c74
  1. 50
      ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs

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

@ -967,28 +967,52 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
Left = new Backreference("fieldReference"), Left = new Backreference("fieldReference"),
Right = new IdentifierExpression("value") Right = new IdentifierExpression("value")
} }
}}}; }}
};
static readonly PropertyDeclaration automaticReadonlyPropertyPattern = new PropertyDeclaration {
Attributes = { new Repeat(new AnyNode()) },
Modifiers = Modifiers.Any,
ReturnType = new AnyNode(),
PrivateImplementationType = new OptionalNode(new AnyNode()),
Name = Pattern.AnyString,
Getter = new Accessor {
Attributes = { new Repeat(new AnyNode()) },
Modifiers = Modifiers.Any,
Body = new BlockStatement {
new ReturnStatement {
Expression = new AnyNode("fieldReference")
}
}
}
};
PropertyDeclaration TransformAutomaticProperties(PropertyDeclaration property) PropertyDeclaration TransformAutomaticProperties(PropertyDeclaration property)
{ {
PropertyDefinition cecilProperty = context.TypeSystem.GetCecil(property.GetSymbol() as IProperty) as PropertyDefinition; PropertyDefinition cecilProperty = context.TypeSystem.GetCecil(property.GetSymbol() as IProperty) as PropertyDefinition;
if (cecilProperty == null || cecilProperty.GetMethod == null || cecilProperty.SetMethod == null) if (cecilProperty == null || cecilProperty.GetMethod == null)
return null; return null;
if (!(cecilProperty.GetMethod.IsCompilerGenerated() && cecilProperty.SetMethod.IsCompilerGenerated())) if (!cecilProperty.GetMethod.IsCompilerGenerated() && (cecilProperty.SetMethod?.IsCompilerGenerated() == false))
return null; return null;
IField fieldInfo = null;
Match m = automaticPropertyPattern.Match(property); Match m = automaticPropertyPattern.Match(property);
if (m.Success) { if (m.Success) {
var fieldInfo = m.Get<AstNode>("fieldReference").Single().GetSymbol() as IField; fieldInfo = m.Get<AstNode>("fieldReference").Single().GetSymbol() as IField;
if (fieldInfo == null) } else {
return null; Match m2 = automaticReadonlyPropertyPattern.Match(property);
FieldDefinition field = context.TypeSystem.GetCecil(fieldInfo) as FieldDefinition; if (m2.Success) {
if (field.IsCompilerGenerated() && field.DeclaringType == cecilProperty.DeclaringType) { fieldInfo = m2.Get<AstNode>("fieldReference").Single().GetSymbol() as IField;
RemoveCompilerGeneratedAttribute(property.Getter.Attributes);
RemoveCompilerGeneratedAttribute(property.Setter.Attributes);
property.Getter.Body = null;
property.Setter.Body = null;
} }
} }
if (fieldInfo == null)
return null;
FieldDefinition field = context.TypeSystem.GetCecil(fieldInfo) as FieldDefinition;
if (field.IsCompilerGenerated() && field.DeclaringType == cecilProperty.DeclaringType) {
RemoveCompilerGeneratedAttribute(property.Getter.Attributes);
RemoveCompilerGeneratedAttribute(property.Setter.Attributes);
property.Getter.Body = null;
property.Setter.Body = null;
}
// Since the property instance is not changed, we can continue in the visitor as usual, so return null // Since the property instance is not changed, we can continue in the visitor as usual, so return null
return null; return null;
} }

Loading…
Cancel
Save