From 7f9d9002bcf4b8f7ad01f846d937a2a7598f5755 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sun, 23 Aug 2020 12:42:34 +0200 Subject: [PATCH] #2104: Generalize auto property backing field name-checking --- .../Transforms/PatternStatementTransform.cs | 32 ++++++++++++++++--- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs b/ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs index 338b889e2..76c6927a1 100644 --- a/ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs +++ b/ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs @@ -586,7 +586,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms field = m2.Get("fieldReference").Single().GetSymbol() as IField; } } - if (field == null || !(field.Name.StartsWith("<") && field.Name.EndsWith(">k__BackingField"))) + if (field == null || !NameCouldBeBackingFieldOfAutomaticProperty(field.Name, out _)) return null; if (propertyDeclaration.Setter.HasModifier(Modifiers.Readonly)) return null; @@ -650,22 +650,44 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms return base.VisitIdentifier(identifier); } + + internal static bool IsBackingFieldOfAutomaticProperty(IField field, out IProperty property) { property = null; - if (!(field.Name.StartsWith("<") && field.Name.EndsWith(">k__BackingField"))) + if (!NameCouldBeBackingFieldOfAutomaticProperty(field.Name, out string propertyName)) return false; if (!field.IsCompilerGenerated()) return false; - var propertyName = field.Name.Substring(1, field.Name.Length - 1 - ">k__BackingField".Length); property = field.DeclaringTypeDefinition - .GetProperties(p => p.Name == propertyName, GetMemberOptions.IgnoreInheritedMembers).FirstOrDefault(); + .GetProperties(p => p.Name == propertyName, GetMemberOptions.IgnoreInheritedMembers) + .FirstOrDefault(); return property != null; } + /// + /// This matches the following patterns + /// + /// <Property>k__BackingField (used by C#) + /// _Property (used by VB) + /// + /// + static readonly System.Text.RegularExpressions.Regex automaticPropertyBackingFieldNameRegex + = new System.Text.RegularExpressions.Regex(@"^(<(?\w+)>k__BackingField|_(?\w+))$"); + + static bool NameCouldBeBackingFieldOfAutomaticProperty(string name, out string propertyName) + { + propertyName = null; + var m = automaticPropertyBackingFieldNameRegex.Match(name); + if (!m.Success) + return false; + propertyName = m.Groups["name"].Value; + return true; + } + Identifier ReplaceBackingFieldUsage(Identifier identifier) { - if (identifier.Name.StartsWith("<") && identifier.Name.EndsWith(">k__BackingField")) { + if (NameCouldBeBackingFieldOfAutomaticProperty(identifier.Name, out _)) { var parent = identifier.Parent; var mrr = parent.Annotation(); var field = mrr?.Member as IField;