@@ -795,13 +795,33 @@ public static MemberDeclarationSyntax GetPropertySyntax(PropertyInfo propertyInf
795795 // Get the property type syntax
796796 TypeSyntax propertyType = IdentifierName ( propertyInfo . TypeNameWithNullabilityAnnotations ) ;
797797
798+ string getterFieldIdentifierName ;
799+ ExpressionSyntax getterFieldExpression ;
800+ ExpressionSyntax setterFieldExpression ;
801+
798802 // In case the backing field is exactly named "value", we need to add the "this." prefix to ensure that comparisons and assignments
799803 // 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" )
801805 {
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+ }
805825
806826 if ( propertyInfo . NotifyPropertyChangedRecipients || propertyInfo . IsOldPropertyValueDirectlyReferenced )
807827 {
@@ -813,7 +833,7 @@ public static MemberDeclarationSyntax GetPropertySyntax(PropertyInfo propertyInf
813833 VariableDeclaration ( propertyType )
814834 . AddVariables (
815835 VariableDeclarator ( Identifier ( "__oldValue" ) )
816- . WithInitializer ( EqualsValueClause ( fieldExpression ) ) ) ) ) ;
836+ . WithInitializer ( EqualsValueClause ( setterFieldExpression ) ) ) ) ) ;
817837 }
818838
819839 // Add the OnPropertyChanging() call first:
@@ -863,7 +883,7 @@ public static MemberDeclarationSyntax GetPropertySyntax(PropertyInfo propertyInf
863883 ExpressionStatement (
864884 AssignmentExpression (
865885 SyntaxKind . SimpleAssignmentExpression ,
866- fieldExpression ,
886+ setterFieldExpression ,
867887 IdentifierName ( "value" ) ) ) ) ;
868888
869889 // If validation is requested, add a call to ValidateProperty:
@@ -959,7 +979,7 @@ public static MemberDeclarationSyntax GetPropertySyntax(PropertyInfo propertyInf
959979 IdentifierName ( "Default" ) ) ,
960980 IdentifierName ( "Equals" ) ) )
961981 . AddArgumentListArguments (
962- Argument ( fieldExpression ) ,
982+ Argument ( setterFieldExpression ) ,
963983 Argument ( IdentifierName ( "value" ) ) ) ) ,
964984 Block ( setterStatements . AsEnumerable ( ) ) ) ;
965985
@@ -1009,13 +1029,13 @@ public static MemberDeclarationSyntax GetPropertySyntax(PropertyInfo propertyInf
10091029 . AddArgumentListArguments (
10101030 AttributeArgument ( LiteralExpression ( SyntaxKind . StringLiteralExpression , Literal ( typeof ( ObservablePropertyGenerator ) . FullName ) ) ) ,
10111031 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 ( ) ) ) ,
10131033 AttributeList ( SingletonSeparatedList ( Attribute ( IdentifierName ( "global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage" ) ) ) ) )
10141034 . AddAttributeLists ( forwardedAttributes . ToArray ( ) )
10151035 . AddModifiers ( Token ( SyntaxKind . PublicKeyword ) )
10161036 . AddAccessorListAccessors (
10171037 AccessorDeclaration ( SyntaxKind . GetAccessorDeclaration )
1018- . WithExpressionBody ( ArrowExpressionClause ( IdentifierName ( propertyInfo . FieldName ) ) )
1038+ . WithExpressionBody ( ArrowExpressionClause ( getterFieldExpression ) )
10191039 . WithSemicolonToken ( Token ( SyntaxKind . SemicolonToken ) ) ,
10201040 setAccessor ) ;
10211041 }
0 commit comments