Browse Source

Fix implementation of ReplaceBackingFieldUsage and ReplaceEventFieldAnnotation (see #540)

pull/992/head
Siegfried Pammer 8 years ago
parent
commit
dc359673f6
  1. 73
      ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs

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

@ -78,16 +78,6 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
result = TransformFor(expressionStatement); result = TransformFor(expressionStatement);
if (result != null) if (result != null)
return result; return result;
if (context.Settings.AutomaticProperties) {
result = ReplaceBackingFieldUsage(expressionStatement);
if (result != null)
return result;
}
if (context.Settings.AutomaticEvents) {
result = ReplaceEventFieldAnnotation(expressionStatement);
if (result != null)
return result;
}
return base.VisitExpressionStatement(expressionStatement); return base.VisitExpressionStatement(expressionStatement);
} }
@ -524,44 +514,59 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
section.Remove(); section.Remove();
} }
} }
#endregion
ExpressionStatement ReplaceBackingFieldUsage(ExpressionStatement expressionStatement) public override AstNode VisitIdentifier(Identifier identifier)
{ {
foreach (var identifier in expressionStatement.Descendants.OfType<Identifier>()) { if (context.Settings.AutomaticProperties) {
if (identifier.Name.StartsWith("<") && identifier.Name.EndsWith(">k__BackingField")) { var newIdentifier = ReplaceBackingFieldUsage(identifier);
var parent = identifier.Parent; if (newIdentifier != null) {
var mrr = parent.Annotation<MemberResolveResult>(); identifier.ReplaceWith(newIdentifier);
var field = mrr?.Member as IField; return newIdentifier;
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) {
identifier.ReplaceWith(Identifier.Create(propertyName));
parent.RemoveAnnotations<MemberResolveResult>();
parent.AddAnnotation(new MemberResolveResult(mrr.TargetResult, property));
}
}
} }
} }
return null; if (context.Settings.AutomaticEvents) {
var newIdentifier = ReplaceEventFieldAnnotation(identifier);
if (newIdentifier != null)
return newIdentifier;
}
return base.VisitIdentifier(identifier);
} }
ExpressionStatement ReplaceEventFieldAnnotation(ExpressionStatement expressionStatement) Identifier ReplaceBackingFieldUsage(Identifier identifier)
{ {
foreach (var identifier in expressionStatement.Descendants.OfType<Identifier>()) { if (identifier.Name.StartsWith("<") && identifier.Name.EndsWith(">k__BackingField")) {
var parent = identifier.Parent; var parent = identifier.Parent;
var mrr = parent.Annotation<MemberResolveResult>(); var mrr = parent.Annotation<MemberResolveResult>();
var field = mrr?.Member as IField; var field = mrr?.Member as IField;
if (field == null) continue; if (field != null && field.IsCompilerGenerated()) {
var @event = field.DeclaringType.GetEvents(ev => ev.Name == field.Name, GetMemberOptions.IgnoreInheritedMembers).SingleOrDefault(); var propertyName = identifier.Name.Substring(1, identifier.Name.Length - 1 - ">k__BackingField".Length);
if (@event != null) { var property = field.DeclaringTypeDefinition.GetProperties(p => p.Name == propertyName, GetMemberOptions.IgnoreInheritedMembers).FirstOrDefault();
parent.RemoveAnnotations<MemberResolveResult>(); if (property != null) {
parent.AddAnnotation(new MemberResolveResult(mrr.TargetResult, @event)); parent.RemoveAnnotations<MemberResolveResult>();
parent.AddAnnotation(new MemberResolveResult(mrr.TargetResult, property));
return Identifier.Create(propertyName);
}
} }
} }
return null; return null;
} }
#endregion
Identifier ReplaceEventFieldAnnotation(Identifier identifier)
{
var parent = identifier.Parent;
var mrr = parent.Annotation<MemberResolveResult>();
var field = mrr?.Member as IField;
if (field == null)
return null;
var @event = field.DeclaringType.GetEvents(ev => ev.Name == field.Name, GetMemberOptions.IgnoreInheritedMembers).SingleOrDefault();
if (@event != null) {
parent.RemoveAnnotations<MemberResolveResult>();
parent.AddAnnotation(new MemberResolveResult(mrr.TargetResult, @event));
return identifier;
}
return null;
}
#region Automatic Events #region Automatic Events
static readonly Accessor automaticEventPatternV2 = new Accessor { static readonly Accessor automaticEventPatternV2 = new Accessor {

Loading…
Cancel
Save