StatementSyntax GeneratePropertySetterAssignment(GClass cl, GProperty prop, bool isObject, bool isNullable) { var code = @$ " // Update the backing value {PropertyBackingFieldName(prop)} = value; // Register object for serialization in the next batch {ChangedFieldsFieldName(cl)} |= {ChangedFieldsTypeName(cl)}.{prop.Name};
ExpressionSyntax ClientProperty(GClass c, GProperty p) => MemberAccess(ServerName(c.Name), CompositionPropertyField(p));
string CompositionPropertyField(GProperty prop) => "s_IdOf" + prop.Name + "Property";
string PropertyBackingFieldName(GProperty prop) => "_" + prop.Name.WithLowerFirst();
private ClassDeclarationSyntax GenerateClientProperty(ClassDeclarationSyntax client, GClass cl, GProperty prop, TypeSyntax propType, bool isObject, bool isNullable) { var fieldName = PropertyBackingFieldName(prop); return(client .AddMembers(DeclareField(prop.Type, fieldName)) .AddMembers(PropertyDeclaration(propType, prop.Name) .AddModifiers(prop.Internal ? SyntaxKind.InternalKeyword : SyntaxKind.PublicKeyword) .AddAccessorListAccessors( AccessorDeclaration(SyntaxKind.GetAccessorDeclaration, Block(ReturnStatement(IdentifierName(fieldName)))), AccessorDeclaration(SyntaxKind.SetAccessorDeclaration, Block( ParseStatement("var changed = false;"), IfStatement(BinaryExpression(SyntaxKind.NotEqualsExpression, IdentifierName(fieldName), IdentifierName("value")), Block( ParseStatement("On" + prop.Name + "Changing();"), ParseStatement("changed = true;"), GeneratePropertySetterAssignment(cl, prop, isObject, isNullable)) ), ExpressionStatement(AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, IdentifierName(fieldName), IdentifierName("value"))), ParseStatement($"if(changed) On" + prop.Name + "Changed();") )).WithModifiers(TokenList(prop.InternalSet ? new[] { Token(SyntaxKind.InternalKeyword) } : Array.Empty <SyntaxToken>())) )) .AddMembers(MethodDeclaration(ParseTypeName("void"), "On" + prop.Name + "Changed") .AddModifiers(SyntaxKind.PartialKeyword).WithSemicolonToken(Semicolon())) .AddMembers(MethodDeclaration(ParseTypeName("void"), "On" + prop.Name + "Changing") .AddModifiers(SyntaxKind.PartialKeyword).WithSemicolonToken(Semicolon()))); }