Skip to content

Commit 4cbf5af

Browse files
Address code review feedback: add annotation for field keyword detection
Co-authored-by: christophwille <[email protected]>
1 parent 750e6a9 commit 4cbf5af

File tree

2 files changed

+17
-5
lines changed

2 files changed

+17
-5
lines changed

ICSharpCode.Decompiler/CSharp/Annotations.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,4 +335,12 @@ public class UseImplicitlyTypedOutAnnotation
335335
{
336336
public static readonly UseImplicitlyTypedOutAnnotation Instance = new UseImplicitlyTypedOutAnnotation();
337337
}
338+
339+
/// <summary>
340+
/// Annotates an Identifier when it was transformed from a backing field reference to the C# 14 'field' keyword.
341+
/// </summary>
342+
public class SemiAutoPropertyFieldKeywordAnnotation
343+
{
344+
public static readonly SemiAutoPropertyFieldKeywordAnnotation Instance = new SemiAutoPropertyFieldKeywordAnnotation();
345+
}
338346
}

ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -677,14 +677,15 @@ void TransformSemiAutoProperty(PropertyDeclaration propertyDeclaration)
677677
IProperty property = propertyDeclaration.GetSymbol() as IProperty;
678678
if (property == null)
679679
return;
680-
// Check if any accessor body contains the 'field' keyword (which was transformed from backing field)
680+
// Check if any accessor body contains an identifier with the SemiAutoPropertyFieldKeywordAnnotation
681+
// (which indicates it was transformed from a backing field reference)
681682
bool usesFieldKeyword = false;
682683
foreach (var accessor in new[] { propertyDeclaration.Getter, propertyDeclaration.Setter })
683684
{
684685
if (accessor.IsNull || accessor.Body.IsNull)
685686
continue;
686687
usesFieldKeyword |= accessor.Body.Descendants.OfType<Identifier>()
687-
.Any(id => id.Name == "field");
688+
.Any(id => id.Annotation<SemiAutoPropertyFieldKeywordAnnotation>() != null);
688689
}
689690
if (!usesFieldKeyword)
690691
return;
@@ -699,15 +700,16 @@ void TransformSemiAutoProperty(PropertyDeclaration propertyDeclaration)
699700
});
700701
if (fieldDecl != null)
701702
{
702-
fieldDecl.Remove();
703-
// Move field attributes to the property with [field: ...] target
703+
// Remove compiler-generated attributes before detaching the node
704704
CSharpDecompiler.RemoveAttribute(fieldDecl, KnownAttribute.CompilerGenerated);
705705
CSharpDecompiler.RemoveAttribute(fieldDecl, KnownAttribute.DebuggerBrowsable);
706+
// Move remaining field attributes to the property with [field: ...] target
706707
foreach (var section in fieldDecl.Attributes)
707708
{
708709
section.AttributeTarget = "field";
709710
propertyDeclaration.Attributes.Add(section.Detach());
710711
}
712+
fieldDecl.Remove();
711713
}
712714
}
713715

@@ -801,7 +803,9 @@ Identifier ReplaceBackingFieldUsage(Identifier identifier)
801803
// We're inside this property's accessor - use the field keyword if enabled
802804
if (context.Settings.SemiAutoProperties)
803805
{
804-
return Identifier.Create("field");
806+
var newIdentifier = Identifier.Create("field");
807+
newIdentifier.AddAnnotation(SemiAutoPropertyFieldKeywordAnnotation.Instance);
808+
return newIdentifier;
805809
}
806810
return null;
807811
}

0 commit comments

Comments
 (0)