@@ -795,13 +795,33 @@ public static MemberDeclarationSyntax GetPropertySyntax(PropertyInfo propertyInf
795
795
// Get the property type syntax
796
796
TypeSyntax propertyType = IdentifierName ( propertyInfo . TypeNameWithNullabilityAnnotations ) ;
797
797
798
+ string getterFieldIdentifierName ;
799
+ ExpressionSyntax getterFieldExpression ;
800
+ ExpressionSyntax setterFieldExpression ;
801
+
798
802
// In case the backing field is exactly named "value", we need to add the "this." prefix to ensure that comparisons and assignments
799
803
// with it in the generated setter body are executed correctly and without conflicts with the implicit value parameter.
800
- ExpressionSyntax fieldExpression = propertyInfo . FieldName switch
804
+ if ( propertyInfo . FieldName == "value" )
801
805
{
802
- "value" => MemberAccessExpression ( SyntaxKind . SimpleMemberAccessExpression , ThisExpression ( ) , IdentifierName ( "value" ) ) ,
803
- string name => IdentifierName ( name )
804
- } ;
806
+ // We only need to add "this." when referencing the field in the setter (getter and XML docs are not ambiguous)
807
+ getterFieldIdentifierName = "value" ;
808
+ getterFieldExpression = IdentifierName ( getterFieldIdentifierName ) ;
809
+ setterFieldExpression = MemberAccessExpression ( SyntaxKind . SimpleMemberAccessExpression , ThisExpression ( ) , ( IdentifierNameSyntax ) getterFieldExpression ) ;
810
+ }
811
+ else if ( SyntaxFacts . GetKeywordKind ( propertyInfo . FieldName ) != SyntaxKind . None ||
812
+ SyntaxFacts . GetContextualKeywordKind ( propertyInfo . FieldName ) != SyntaxKind . None )
813
+ {
814
+ // If the identifier for the field could potentially be a keyword, we must escape it.
815
+ // This usually happens if the annotated field was escaped as well (eg. "@event").
816
+ // In this case, we must always escape the identifier, in all cases.
817
+ getterFieldIdentifierName = $ "@{ propertyInfo . FieldName } ";
818
+ getterFieldExpression = setterFieldExpression = IdentifierName ( getterFieldIdentifierName ) ;
819
+ }
820
+ else
821
+ {
822
+ getterFieldIdentifierName = propertyInfo . FieldName ;
823
+ getterFieldExpression = setterFieldExpression = IdentifierName ( getterFieldIdentifierName ) ;
824
+ }
805
825
806
826
if ( propertyInfo . NotifyPropertyChangedRecipients || propertyInfo . IsOldPropertyValueDirectlyReferenced )
807
827
{
@@ -813,7 +833,7 @@ public static MemberDeclarationSyntax GetPropertySyntax(PropertyInfo propertyInf
813
833
VariableDeclaration ( propertyType )
814
834
. AddVariables (
815
835
VariableDeclarator ( Identifier ( "__oldValue" ) )
816
- . WithInitializer ( EqualsValueClause ( fieldExpression ) ) ) ) ) ;
836
+ . WithInitializer ( EqualsValueClause ( setterFieldExpression ) ) ) ) ) ;
817
837
}
818
838
819
839
// Add the OnPropertyChanging() call first:
@@ -863,7 +883,7 @@ public static MemberDeclarationSyntax GetPropertySyntax(PropertyInfo propertyInf
863
883
ExpressionStatement (
864
884
AssignmentExpression (
865
885
SyntaxKind . SimpleAssignmentExpression ,
866
- fieldExpression ,
886
+ setterFieldExpression ,
867
887
IdentifierName ( "value" ) ) ) ) ;
868
888
869
889
// If validation is requested, add a call to ValidateProperty:
@@ -959,7 +979,7 @@ public static MemberDeclarationSyntax GetPropertySyntax(PropertyInfo propertyInf
959
979
IdentifierName ( "Default" ) ) ,
960
980
IdentifierName ( "Equals" ) ) )
961
981
. AddArgumentListArguments (
962
- Argument ( fieldExpression ) ,
982
+ Argument ( setterFieldExpression ) ,
963
983
Argument ( IdentifierName ( "value" ) ) ) ) ,
964
984
Block ( setterStatements . AsEnumerable ( ) ) ) ;
965
985
@@ -1009,13 +1029,13 @@ public static MemberDeclarationSyntax GetPropertySyntax(PropertyInfo propertyInf
1009
1029
. AddArgumentListArguments (
1010
1030
AttributeArgument ( LiteralExpression ( SyntaxKind . StringLiteralExpression , Literal ( typeof ( ObservablePropertyGenerator ) . FullName ) ) ) ,
1011
1031
AttributeArgument ( LiteralExpression ( SyntaxKind . StringLiteralExpression , Literal ( typeof ( ObservablePropertyGenerator ) . Assembly . GetName ( ) . Version . ToString ( ) ) ) ) ) ) )
1012
- . WithOpenBracketToken ( Token ( TriviaList ( Comment ( $ "/// <inheritdoc cref=\" { propertyInfo . FieldName } \" />") ) , SyntaxKind . OpenBracketToken , TriviaList ( ) ) ) ,
1032
+ . WithOpenBracketToken ( Token ( TriviaList ( Comment ( $ "/// <inheritdoc cref=\" { getterFieldIdentifierName } \" />") ) , SyntaxKind . OpenBracketToken , TriviaList ( ) ) ) ,
1013
1033
AttributeList ( SingletonSeparatedList ( Attribute ( IdentifierName ( "global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage" ) ) ) ) )
1014
1034
. AddAttributeLists ( forwardedAttributes . ToArray ( ) )
1015
1035
. AddModifiers ( Token ( SyntaxKind . PublicKeyword ) )
1016
1036
. AddAccessorListAccessors (
1017
1037
AccessorDeclaration ( SyntaxKind . GetAccessorDeclaration )
1018
- . WithExpressionBody ( ArrowExpressionClause ( IdentifierName ( propertyInfo . FieldName ) ) )
1038
+ . WithExpressionBody ( ArrowExpressionClause ( getterFieldExpression ) )
1019
1039
. WithSemicolonToken ( Token ( SyntaxKind . SemicolonToken ) ) ,
1020
1040
setAccessor ) ;
1021
1041
}
0 commit comments