<commit_before>using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
using static Avalonia.SourceGenerator.CompositionGenerator.Extensions;
namespace Avalonia.SourceGenerator.CompositionGenerator
{
    public partial class Generator
    {
        private readonly ICompositionGeneratorSink _output;
        private readonly GConfig _config;
        private readonly HashSet<string> _objects;
        private readonly HashSet<string> _brushes;
        private readonly Dictionary<string, GManualClass> _manuals;
        public Generator(ICompositionGeneratorSink output, GConfig config)
        {
            _output = output;
            _config = config;
            _manuals = _config.ManualClasses.ToDictionary(x => x.Name);
            _objects = new HashSet<string>(_config.ManualClasses.Select(x => x.Name)
                .Concat(_config.Classes.Select(x => x.Name)));
            _brushes = new HashSet<string>(_config.Classes.OfType<GBrush>().Select(x => x.Name)) {"CompositionBrush"};
        }

        
        
        public void Generate()
        {
            foreach (var cl in _config.Classes)
                GenerateClass(cl);
            
            GenerateAnimations();
        }



        string ServerName(string? c) => c != null ? ("Server" + c) : "ServerObject";
        string ChangesName(string? c) => c != null ? (c + "Changes") : "ChangeSet";
        string ChangedFieldsTypeName(GClass c) => c.Name + "ChangedFields";
        string ChangedFieldsFieldName(GClass c) =>  "_changedFieldsOf" + c.Name;
        string PropertyBackingFieldName(GProperty prop) => "_" + prop.Name.WithLowerFirst();
        string CompositionPropertyField(GProperty prop) => "s_IdOf" + prop.Name + "Property";

        ExpressionSyntax ClientProperty(GClass c, GProperty p) =>
            MemberAccess(ServerName(c.Name), CompositionPropertyField(p));

        void GenerateClass(GClass cl)
        {
            var list = cl as GList;
            
            var unit = Unit();
            
            var clientNs = NamespaceDeclaration(IdentifierName("Avalonia.Rendering.Composition"));
            var serverNs = NamespaceDeclaration(IdentifierName("Avalonia.Rendering.Composition.Server"));
            var transportNs = NamespaceDeclaration(IdentifierName("Avalonia.Rendering.Composition.Transport"));

            var inherits = cl.Inherits ?? "CompositionObject";
            var abstractModifier = cl.Abstract ? new[] {SyntaxKind.AbstractKeyword} : null;
            
            var client = ClassDeclaration(cl.Name)
                .AddModifiers(abstractModifier)
                .AddModifiers(SyntaxKind.PublicKeyword, SyntaxKind.UnsafeKeyword, SyntaxKind.PartialKeyword)
                .WithBaseType(inherits);
            
            var serverName = ServerName(cl.Name);
            var serverBase = cl.ServerBase ?? ServerName(cl.Inherits);
            if (list != null)
                serverBase = "ServerList<" + ServerName(list.ItemType) + ">";
            
            var server = ClassDeclaration(serverName)
                .AddModifiers(abstractModifier)
                .AddModifiers(SyntaxKind.UnsafeKeyword, SyntaxKind.PartialKeyword)
                .WithBaseType(serverBase);

            string changesName = ChangesName(cl.Name);
            string changedFieldsTypeName = ChangedFieldsTypeName(cl);
            string changedFieldsName = ChangedFieldsFieldName(cl);

            if (cl.Properties.Count > 0)
                client = client
                    .AddMembers(DeclareField(changedFieldsTypeName, changedFieldsName));
            
            
            if (!cl.CustomCtor)
            {
                client = client.AddMembers(PropertyDeclaration(ParseTypeName(serverName), "Server")
                    .AddModifiers(SyntaxKind.InternalKeyword, SyntaxKind.NewKeyword)
                    .AddAccessorListAccessors(AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
                        .WithSemicolonToken(Semicolon())));
            client = client.AddMembers(
                    ConstructorDeclaration(cl.Name)
                        .AddModifiers(SyntaxKind.InternalKeyword)
                        .WithParameterList(ParameterList(SeparatedList(new[]
                        {
                            Parameter(Identifier("compositor")).WithType(ParseTypeName("Compositor")),
                            Parameter(Identifier("server")).WithType(ParseTypeName(serverName)),
                        })))
                        .WithInitializer(ConstructorInitializer(SyntaxKind.BaseConstructorInitializer,
                            ArgumentList(SeparatedList(new[]
                            {
                                Argument(IdentifierName("compositor")),
                                Argument(IdentifierName("server")),
                            })))).WithBody(Block(
                            ExpressionStatement(
                                AssignmentExpression(
                                    SyntaxKind.SimpleAssignmentExpression,
                                    IdentifierName("Server"),
                                    CastExpression(ParseTypeName(serverName), IdentifierName("server")))),
                            ExpressionStatement(InvocationExpression(IdentifierName("InitializeDefaults")))
                        )));
            }

            if (!cl.CustomServerCtor)
            {
                server = server.AddMembers(
                    ConstructorDeclaration(serverName)
                        .AddModifiers(SyntaxKind.InternalKeyword)
                        .WithParameterList(ParameterList(SeparatedList(new[]
                        {
                            Parameter(Identifier("compositor")).WithType(ParseTypeName("ServerCompositor")),
                        })))
                        .WithInitializer(ConstructorInitializer(SyntaxKind.BaseConstructorInitializer,
                            ArgumentList(SeparatedList(new[]
                            {
                                Argument(IdentifierName("compositor")),
                            })))).WithBody(Block(ParseStatement("Initialize();"))));
            }

            server = server.AddMembers(
                MethodDeclaration(ParseTypeName("void"), "Initialize")
                    .AddModifiers(SyntaxKind.PartialKeyword).WithSemicolonToken(Semicolon()));


            var changesVarName = "c";
            var changesVar = IdentifierName(changesVarName);

            server = server.AddMembers(
                MethodDeclaration(ParseTypeName("void"), "DeserializeChangesExtra")
                    .AddParameterListParameters(Parameter(Identifier("c")).WithType(ParseTypeName("BatchStreamReader")))
                    .AddModifiers(SyntaxKind.PartialKeyword).WithSemicolonToken(Semicolon()));

            var resetBody = Block();<commit_msg>fix(DevGenerator): The variable 'changesVar' is assigned but its value is never used<commit_after>using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
using static Avalonia.SourceGenerator.CompositionGenerator.Extensions;
namespace Avalonia.SourceGenerator.CompositionGenerator
{
    public partial class Generator
    {
        private readonly ICompositionGeneratorSink _output;
        private readonly GConfig _config;
        private readonly HashSet<string> _objects;
        private readonly HashSet<string> _brushes;
        private readonly Dictionary<string, GManualClass> _manuals;
        public Generator(ICompositionGeneratorSink output, GConfig config)
        {
            _output = output;
            _config = config;
            _manuals = _config.ManualClasses.ToDictionary(x => x.Name);
            _objects = new HashSet<string>(_config.ManualClasses.Select(x => x.Name)
                .Concat(_config.Classes.Select(x => x.Name)));
            _brushes = new HashSet<string>(_config.Classes.OfType<GBrush>().Select(x => x.Name)) {"CompositionBrush"};
        }

        
        
        public void Generate()
        {
            foreach (var cl in _config.Classes)
                GenerateClass(cl);
            
            GenerateAnimations();
        }



        string ServerName(string? c) => c != null ? ("Server" + c) : "ServerObject";
        string ChangesName(string? c) => c != null ? (c + "Changes") : "ChangeSet";
        string ChangedFieldsTypeName(GClass c) => c.Name + "ChangedFields";
        string ChangedFieldsFieldName(GClass c) =>  "_changedFieldsOf" + c.Name;
        string PropertyBackingFieldName(GProperty prop) => "_" + prop.Name.WithLowerFirst();
        string CompositionPropertyField(GProperty prop) => "s_IdOf" + prop.Name + "Property";

        ExpressionSyntax ClientProperty(GClass c, GProperty p) =>
            MemberAccess(ServerName(c.Name), CompositionPropertyField(p));

        void GenerateClass(GClass cl)
        {
            var list = cl as GList;
            
            var unit = Unit();
            
            var clientNs = NamespaceDeclaration(IdentifierName("Avalonia.Rendering.Composition"));
            var serverNs = NamespaceDeclaration(IdentifierName("Avalonia.Rendering.Composition.Server"));
            var transportNs = NamespaceDeclaration(IdentifierName("Avalonia.Rendering.Composition.Transport"));

            var inherits = cl.Inherits ?? "CompositionObject";
            var abstractModifier = cl.Abstract ? new[] {SyntaxKind.AbstractKeyword} : null;
            
            var client = ClassDeclaration(cl.Name)
                .AddModifiers(abstractModifier)
                .AddModifiers(SyntaxKind.PublicKeyword, SyntaxKind.UnsafeKeyword, SyntaxKind.PartialKeyword)
                .WithBaseType(inherits);
            
            var serverName = ServerName(cl.Name);
            var serverBase = cl.ServerBase ?? ServerName(cl.Inherits);
            if (list != null)
                serverBase = "ServerList<" + ServerName(list.ItemType) + ">";
            
            var server = ClassDeclaration(serverName)
                .AddModifiers(abstractModifier)
                .AddModifiers(SyntaxKind.UnsafeKeyword, SyntaxKind.PartialKeyword)
                .WithBaseType(serverBase);

            string changesName = ChangesName(cl.Name);
            string changedFieldsTypeName = ChangedFieldsTypeName(cl);
            string changedFieldsName = ChangedFieldsFieldName(cl);

            if (cl.Properties.Count > 0)
                client = client
                    .AddMembers(DeclareField(changedFieldsTypeName, changedFieldsName));
            
            
            if (!cl.CustomCtor)
            {
                client = client.AddMembers(PropertyDeclaration(ParseTypeName(serverName), "Server")
                    .AddModifiers(SyntaxKind.InternalKeyword, SyntaxKind.NewKeyword)
                    .AddAccessorListAccessors(AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
                        .WithSemicolonToken(Semicolon())));
            client = client.AddMembers(
                    ConstructorDeclaration(cl.Name)
                        .AddModifiers(SyntaxKind.InternalKeyword)
                        .WithParameterList(ParameterList(SeparatedList(new[]
                        {
                            Parameter(Identifier("compositor")).WithType(ParseTypeName("Compositor")),
                            Parameter(Identifier("server")).WithType(ParseTypeName(serverName)),
                        })))
                        .WithInitializer(ConstructorInitializer(SyntaxKind.BaseConstructorInitializer,
                            ArgumentList(SeparatedList(new[]
                            {
                                Argument(IdentifierName("compositor")),
                                Argument(IdentifierName("server")),
                            })))).WithBody(Block(
                            ExpressionStatement(
                                AssignmentExpression(
                                    SyntaxKind.SimpleAssignmentExpression,
                                    IdentifierName("Server"),
                                    CastExpression(ParseTypeName(serverName), IdentifierName("server")))),
                            ExpressionStatement(InvocationExpression(IdentifierName("InitializeDefaults")))
                        )));
            }

            if (!cl.CustomServerCtor)
            {
                server = server.AddMembers(
                    ConstructorDeclaration(serverName)
                        .AddModifiers(SyntaxKind.InternalKeyword)
                        .WithParameterList(ParameterList(SeparatedList(new[]
                        {
                            Parameter(Identifier("compositor")).WithType(ParseTypeName("ServerCompositor")),
                        })))
                        .WithInitializer(ConstructorInitializer(SyntaxKind.BaseConstructorInitializer,
                            ArgumentList(SeparatedList(new[]
                            {
                                Argument(IdentifierName("compositor")),
                            })))).WithBody(Block(ParseStatement("Initialize();"))));
            }

            server = server.AddMembers(
                MethodDeclaration(ParseTypeName("void"), "Initialize")
                    .AddModifiers(SyntaxKind.PartialKeyword).WithSemicolonToken(Semicolon()));

            server = server.AddMembers(
                MethodDeclaration(ParseTypeName("void"), "DeserializeChangesExtra")
                    .AddParameterListParameters(Parameter(Identifier("c")).WithType(ParseTypeName("BatchStreamReader")))
                    .AddModifiers(SyntaxKind.PartialKeyword).WithSemicolonToken(Semicolon()));

            var resetBody = Block();
{'fraction_non_alphanumeric': 0.09244828563332388, 'fraction_numerical': 0.00014168319637291018, 'mean_word_length': 1.959538784067086, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2139650', 'n_tokens_mistral': 3323, 'n_tokens_neox': 3240, 'n_words': 514}