Example #1
0
        /// <summary>
        /// Vérifie que la classe passée en paramètre respecte les conditions pour être marquée sérializable
        /// (si elle l'est).
        /// </summary>
        void PerformSerializableChecking(Language.ClassDeclaration decl, Semantic.TypeTable types)
        {
            Language.ClankType type = types.Types[decl.Name];
            if (!type.SupportSerialization)
            {
                return;
            }

            bool   hasError = false;
            string error    = "La classe '" + decl.Name + "' est marquée serializable mais contient des variables non serializables : ";

            // Vérifie que les types des variables d'instances sont tous "serializable".
            foreach (var kvp in type.InstanceVariables)
            {
                string            name     = kvp.Key;
                Language.Variable variable = kvp.Value;
                // Si la variable a des paramètres génériqu
                if (variable.Type.BaseType.HasGenericParameterTypeMembers())
                {
                    /*if(!variable.Type.BaseType.SupportSerializationAsGeneric)
                     * {
                     *  hasError = true;
                     *  error += variable.ToString() + " ne supporte pas la sérialisation en tant que param générique, ";
                     * }*/
                    // On ne peut pas check maintenant, il faut connaître les params génériques.
                }
                else if (!(variable.Type.BaseType is Language.GenericParameterType))
                {
                    List <string> dummy;
                    if (!variable.Type.DoesSupportSerialization(out dummy))
                    {
                        hasError = true;
                        error   += variable.ToString() + "ne supporte pas la sérialisation, ";
                    }
                }
            }

            if (hasError)
            {
                error = error.TrimEnd(',', ' ');
                ParsingLog.AddWarning(error, decl.Line, decl.Character, decl.Source);
            }
        }
Example #2
0
        /// <summary>
        /// Génère un modèle abstrait représentant les classes à créer pour le serveur du projet cible.
        /// </summary>
        /// <returns></returns>
        public List <Language.Instruction> GenerateServerProject()
        {
            List <Language.Instruction> classes = new List <Language.Instruction>();

            // Copie de la classe state
            Language.ClassDeclaration stateClass = State.StateClass.Copy();
            stateClass.Modifiers.Add("public");
            stateClass.Comment = "Contient toutes les informations concernant l'état du serveur.";

            // Copie des classes state
            List <Language.ClassDeclaration> stateClasses = new List <Language.ClassDeclaration>();

            foreach (Language.ClassDeclaration decl in State.Classes)
            {
                stateClasses.Add(decl.Copy());
            }
            ;

            // Ajoute les enums.
            classes.AddRange(stateClass.Instructions.Where((Language.Instruction inst) =>
            {
                return(inst is Language.EnumDeclaration);
            }));

            // Ne conserve que les fonctions dans la classe state.
            stateClass.Instructions = stateClass.Instructions.Where((Language.Instruction inst) =>
            {
                // Ne garde que les fonctions.
                return(inst is Language.FunctionDeclaration);
            }).ToList();

            // Ajoute les méthodes access / write.
            foreach (Language.FunctionDeclaration method in Access.Declarations)
            {
                Language.FunctionDeclaration cpy = method.FuncCopy();
                cpy.Func.Arguments.Add(new Language.FunctionArgument()
                {
                    ArgType = Types.FetchInstancedType("int", new Semantic.TypeTable.Context()), ArgName = Language.SemanticConstants.ClientID
                });
                stateClass.Instructions.Add(cpy);
            }

            foreach (Language.FunctionDeclaration method in Write.Declarations)
            {
                Language.FunctionDeclaration cpy = method.FuncCopy();
                cpy.Func.Arguments.Add(new Language.FunctionArgument()
                {
                    ArgType = Types.FetchInstancedType("int", new Semantic.TypeTable.Context()), ArgName = Language.SemanticConstants.ClientID
                });
                stateClass.Instructions.Add(cpy);
            }

            // Ajoute la méthode de traitement des messages.
            // Le code effectif de cette méthode est créé par le générateur de code
            // du language cible.
            Language.Macros.ProcessMessageMacro processFunc = new Language.Macros.ProcessMessageMacro(Access, Write);
            processFunc.Comment = "Génère le code pour la fonction de traitement des messages.";
            stateClass.Instructions.Add(processFunc);



            // Classe de message
            //Language.ClassDeclaration messageClass = new Language.ClassDeclaration() { Name = "_Message" };
            //messageClass.Instructions.Add(new Language.VariableDeclarationInstruction() { Var = new Language.Variable() { Name = "Type", Type = enumMessageTypeInstance } });

            // Classes de message
            //List<Language.ClassDeclaration> messageClasses = new List<Language.ClassDeclaration>();
#if false
            // Ajout des fonctions de Write.
            #region Write
            foreach (Language.FunctionDeclaration ex in Write.Declarations)
            {
                // Membre de l'enum de message
                enumDecl.Members.Add("MessageType_" + ex.Func.Name);

                // Classe de message
                Language.ClankType klassType = new Language.ClankType()
                {
                    Name = "Write_" + ex.Func.Name + "_Message"
                };
                Language.ClassDeclaration klass = new Language.ClassDeclaration();
                klass.Name = klassType.Name;

                // Création d'un constructeur.
                Language.Constructor cons = new Language.Constructor();
                cons.Owner = klassType;

                // Création :
                // Des variables d'instance de la classe.
                // Des paramètres du constructeur, de l'initialisation de ces paramètres
                foreach (Language.FunctionArgument arg in ex.Func.Arguments)
                {
                    Language.Variable argVar = new Language.Variable()
                    {
                        Name = "_" + arg.ArgName, Type = arg.ArgType
                    };

                    // Déclaration de la variable
                    klass.Instructions.Add(new Language.VariableDeclarationInstruction()
                    {
                        Var = argVar, Modifiers = new List <string>()
                        {
                            "public"
                        }
                    });

                    // Ajout de l'argument au constructeur.
                    cons.Arguments.Add(arg);

                    // Ajout de l'assignement de la variable
                    cons.Code.Add(new Language.AffectationInstruction()
                    {
                        Expression = new Language.BinaryExpressionGroup()
                        {
                            Operand1 = argVar,
                            Operand2 = new Language.Variable()
                            {
                                Name = arg.ArgName, Type = arg.ArgType
                            },
                            Operator = Language.Operator.Affectation
                        }
                    });
                }

                // Ajout de la nouvelle classe.
                klass.Instructions.Add(new Language.ConstructorDeclaration()
                {
                    Func = cons
                });
                messageClasses.Add(klass);

                // Déclaration de fonction dans State.
                stateClass.Instructions.Add(ex);
            }
            #endregion


            // Ajout des fonctions de Access.
            #region Access
            foreach (Language.FunctionDeclaration decl in Access.Declarations)
            {
                // Membre de l'enum de message
                enumDecl.Members.Add("MessageType_" + decl.Func.Name);

                // Classe de message
                Language.ClankType klassType = new Language.ClankType()
                {
                    Name = "Access_" + decl.Func.Name + "_Message"
                };
                Language.ClassDeclaration klass = new Language.ClassDeclaration();
                klass.Name = klassType.Name;

                // Création d'un constructeur.
                Language.Constructor cons = new Language.Constructor();
                cons.Owner = klassType;

                // Création :
                // Des variables d'instance de la classe.
                // Des paramètres du constructeur, de l'initialisation de ces paramètres
                foreach (Language.FunctionArgument arg in decl.Func.Arguments)
                {
                    Language.Variable argVar = new Language.Variable()
                    {
                        Name = "_" + arg.ArgName, Type = arg.ArgType
                    };

                    // Déclaration de la variable
                    klass.Instructions.Add(new Language.VariableDeclarationInstruction()
                    {
                        Var = argVar, Modifiers = new List <string>()
                        {
                            "public"
                        }
                    });

                    // Ajout de l'argument au constructeur.
                    cons.Arguments.Add(arg);

                    // Ajout de l'assignement de la variable
                    cons.Code.Add(new Language.AffectationInstruction()
                    {
                        Expression = new Language.BinaryExpressionGroup()
                        {
                            Operand1 = argVar,
                            Operand2 = new Language.Variable()
                            {
                                Name = arg.ArgName, Type = arg.ArgType
                            },
                            Operator = Language.Operator.Affectation
                        }
                    });
                }

                // Ajout de la nouvelle classe.
                klass.Instructions.Add(new Language.ConstructorDeclaration()
                {
                    Func = cons
                });
                messageClasses.Add(klass);

                // Déclaration de fonction dans State.
                stateClass.Instructions.Add(decl);
            }
            #endregion
#endif

            //classes.AddRange(messageClasses);
            classes.AddRange(stateClasses);
            classes.Add(stateClass);
            return(classes);
        }