public static IEnumerable <SyntaxNode> BuildVariable(this RoslynTranslator translator, IVariableModel v, IPortModel portModel)
        {
            if (v is IConstantNodeModel constantNodeModel)
            {
                if (constantNodeModel.ObjectValue != null)
                {
                    if (constantNodeModel is IStringWrapperConstantModel)
                    {
                        yield return(translator.Constant(constantNodeModel.ObjectValue.ToString(), translator.Stencil));
                    }
                    else
                    {
                        yield return(translator.Constant(constantNodeModel.ObjectValue, translator.Stencil));
                    }
                }

                yield break;
            }

            if (translator.InMacro.Count > 0 && v.DeclarationModel.VariableType == VariableType.GraphVariable && v.DeclarationModel.Modifiers == ModifierFlags.ReadOnly)
            {
                MacroRefNodeModel oldValue = translator.InMacro.Pop();

                var syntaxNodes = translator.BuildPort(oldValue.InputsById[v.DeclarationModel.VariableName]);
                translator.InMacro.Push(oldValue);
                foreach (var syntaxNode in syntaxNodes)
                {
                    yield return(syntaxNode);
                }
                yield break;
            }

            switch (v.DeclarationModel.VariableType)
            {
            case VariableType.FunctionVariable:
            case VariableType.GraphVariable:
            case VariableType.ComponentQueryField:
                yield return(RoslynBuilder.LocalVariableReference(v.DeclarationModel.Name));

                break;

            case VariableType.FunctionParameter:
                yield return(RoslynBuilder.ArgumentReference(v.DeclarationModel.Name));

                break;

//                case VariableType.Literal:
//                case VariableType.InlineExpression:
            default:
                throw new ArgumentOutOfRangeException();
            }
        }
        public ClassDeclarationSyntax Build(RoslynTranslator translator, VSGraphModel graphModel)
        {
            var baseClass = m_NeedToCompleteDependenciesFirst ? nameof(ComponentSystem) : nameof(JobComponentSystem);

            m_ClassDeclaration = m_ClassDeclaration.WithBaseList(
                BaseList(
                    SingletonSeparatedList <BaseTypeSyntax>(
                        SimpleBaseType(
                            IdentifierName(baseClass)))));

            foreach (var queryTracking in m_QueryHasStateTracking)
            {
                var trackingMembers = new List <MemberDeclarationSyntax>();
                if (queryTracking.Value.Tracking)
                {
                    trackingMembers.Add(
                        FieldDeclaration(
                            VariableDeclaration(
                                PredefinedType(
                                    Token(SyntaxKind.BoolKeyword)))
                            .WithVariables(
                                SingletonSeparatedList(
                                    VariableDeclarator(
                                        Identifier("Processed")))))
                        .WithModifiers(
                            TokenList(
                                Token(SyntaxKind.InternalKeyword))));
                }

                DeclareComponent <ISystemStateComponentData>(queryTracking.Value.ComponentName, trackingMembers);
            }

            foreach (var eventSystem in m_EventSystems)
            {
                //  ClearEvents<TestEvent2>.Initialize(World);
                InitializationStatements.Add(ExpressionStatement(InvocationExpression(
                                                                     MemberAccessExpression(
                                                                         SyntaxKind.SimpleMemberAccessExpression,
                                                                         GenericName(
                                                                             Identifier("EventSystem"))
                                                                         .WithTypeArgumentList(
                                                                             TypeArgumentList(
                                                                                 SingletonSeparatedList <TypeSyntax>(
                                                                                     IdentifierName(eventSystem.FullName)))),
                                                                         IdentifierName("Initialize")))
                                                                 .WithArgumentList(
                                                                     ArgumentList(
                                                                         SingletonSeparatedList(
                                                                             Argument(
                                                                                 IdentifierName("World")))))));
            }

            if ((TranslationOptions & RoslynEcsTranslator.TranslationOptions.Tracing) != 0)
            {
                DeclareAndInitField(typeof(TracingRecorderSystem), nameof(TracingRecorderSystem), initValue: InvocationExpression(
                                        MemberAccessExpression(
                                            SyntaxKind.SimpleMemberAccessExpression,
                                            IdentifierName("World"),
                                            GenericName(
                                                Identifier(nameof(World.GetExistingSystem)))
                                            .WithTypeArgumentList(
                                                TypeArgumentList(
                                                    SingletonSeparatedList <TypeSyntax>(
                                                        IdentifierName(nameof(TracingRecorderSystem))))))));
            }
            HashSet <string> declaredQueries = new HashSet <string>();

            foreach (var group in m_WrittenComponentsPerGroup)
            {
                declaredQueries.Add(group.Key.Query.ComponentQueryDeclarationModel.GetId());
                DeclareEntityQueries(group.Value);
            }

            // declare unused queries in case there's a Count Entities In Query node somewhere
            foreach (var graphVariable in graphModel.GraphVariableModels.OfType <ComponentQueryDeclarationModel>().Where(q => !declaredQueries.Contains(q.GetId())))
            {
                var args = graphVariable.Components.Select(c => SyntaxFactory.Argument(
                                                               InvocationExpression(
                                                                   MemberAccessExpression(
                                                                       SyntaxKind.SimpleMemberAccessExpression,
                                                                       IdentifierName("ComponentType"),
                                                                       GenericName(
                                                                           Identifier("ReadOnly"))
                                                                       .WithTypeArgumentList(
                                                                           TypeArgumentList(
                                                                               SingletonSeparatedList <TypeSyntax>(
                                                                                   IdentifierName(c.Component.TypeHandle.Resolve(graphModel.Stencil)
                                                                                                  .FullName))))))
                                                               ));
                var initValue = MakeInitQueryExpression(args);

                DeclareAndInitField(typeof(EntityQuery), graphVariable.VariableName, initValue: initValue);
            }


            var singletonMembers = new List <FieldDeclarationSyntax>();
            var initArguments    = new List <AssignmentExpressionSyntax>();

            foreach (var graphVariable in graphModel.GraphVariableModels
                     .Where(g => g.VariableType == VariableType.GraphVariable))
            {
                singletonMembers.Add(graphVariable.DeclareField(translator, false)
                                     .WithAdditionalAnnotations(new SyntaxAnnotation(Annotations.VariableAnnotationKind)));
                initArguments.Add(RoslynBuilder.Assignment(
                                      IdentifierName(graphVariable.VariableName),
                                      translator.Constant(graphVariable.InitializationModel.ObjectValue, m_Stencil)));
            }

            if (singletonMembers.Any())
            {
                DeclareComponent <IComponentData>(SingletonComponentTypeName, singletonMembers);
                InitializationStatements.Add(ExpressionStatement(
                                                 RoslynBuilder.MethodInvocation(
                                                     nameof(EntityManager.CreateEntity),
                                                     IdentifierName(nameof(EntityManager)),
                                                     new[]
                {
                    Argument(TypeOfExpression(IdentifierName(SingletonComponentTypeName)))
                },
                                                     Enumerable.Empty <TypeSyntax>())));
                InitializationStatements.Add(
                    ExpressionStatement(
                        RoslynBuilder.MethodInvocation(
                            SafeGuardNamingSystem.SetSingletonName,
                            null,
                            new[]
                {
                    Argument(RoslynBuilder.DeclareNewObject(
                                 IdentifierName(SingletonComponentTypeName),
                                 Enumerable.Empty <ArgumentSyntax>(),
                                 initArguments))
                },
                            Enumerable.Empty <TypeSyntax>())));
            }

            // TODO : Remove this once there is real Systems' dependency tool
            var attributes = new List <AttributeListSyntax>();

            foreach (var assetModel in m_Stencil.UpdateAfter.Where(a => a.GraphModel.Stencil is EcsStencil))
            {
                RegisterAttributes <UpdateAfterAttribute>(attributes, assetModel.Name);
            }

            foreach (var assetModel in m_Stencil.UpdateBefore.Where(a => a.GraphModel.Stencil is EcsStencil))
            {
                RegisterAttributes <UpdateBeforeAttribute>(attributes, assetModel.Name);
            }

            m_ClassDeclaration = m_ClassDeclaration
                                 .AddAttributeLists(attributes.ToArray())
                                 .AddMembers(m_ClassMembers.OrderBy(x => x is FieldDeclarationSyntax ? 0 : 1).ToArray());

            if (m_InitializationStatements != null)
            {
                var onCreateManagerOverride = RoslynBuilder.DeclareMethod(
                    SafeGuardNamingSystem.OnCreateManagerName,
                    AccessibilityFlags.Protected | AccessibilityFlags.Override,
                    typeof(void));
                m_ClassDeclaration = m_ClassDeclaration
                                     .AddMembers(
                    onCreateManagerOverride.WithBody(
                        Block(m_InitializationStatements)));
            }

            if (m_SingletonUpdateSyntax != null)
            {
                AddStatement(m_SingletonUpdateSyntax);
            }

            var onUpdateBlock = Block(m_UpdateStatements);

            return(m_ClassDeclaration.AddMembers(
                       RoslynEcsTranslator.MakeOnUpdateOverride(
                           onUpdateBlock,
                           m_NeedToCompleteDependenciesFirst,
                           m_CreatedManagers)));
        }