/// <summary> /// Parse le script et ajoute les champs trouvés dans les différents blocks. /// </summary> public void ParseScript(Language.NamedBlockDeclaration block) { Access.AddDeclarationsFromScript(block, Types); State.AddDeclarationsFromScript(block, Types); Macros.AddDeclarationsFromScript(block, Types); Write.AddDeclarationsFromScript(block, Types); }
/// <summary> /// Ajoute des déclarations à ce Container à partir d'un block Access. /// </summary> /// <param name="block"></param> void AddDeclarationsFromStateBlock(Language.NamedBlockDeclaration block, Semantic.TypeTable types) { foreach (Language.Instruction instruction in block.Instructions) { if (instruction is Language.ClassDeclaration) { PerformSerializableChecking((Language.ClassDeclaration)instruction, types); Classes.Add((Language.ClassDeclaration)instruction); } else if (instruction is Language.EnumDeclaration) { StateClass.Instructions.Add(instruction); } else if (instruction is Language.VariableDeclarationInstruction) { Language.VariableDeclarationInstruction variable = (Language.VariableDeclarationInstruction)instruction; StateClass.Instructions.Add(variable); } else if (instruction is Language.PlaceholderInstruction) { } else { ParsingLog.AddError("Instruction de type " + instruction.GetType().Name + " invalide dans un StateBlock", instruction.Line, instruction.Character, instruction.Source ); } } }
/// <summary> /// Ajoute des déclarations à ce Container à partir d'un block Access. /// </summary> /// <param name="block"></param> void AddDeclarationsFromAccessBlock(Language.NamedBlockDeclaration block, Semantic.TypeTable table) { foreach (Language.Instruction instruction in block.Instructions) { if (instruction is Language.FunctionDeclaration) { // Vérifie que le type de retour de la fonction est public. Language.FunctionDeclaration decl = (Language.FunctionDeclaration)instruction; decl.Func.Owner = table.Types[Language.SemanticConstants.StateClass]; if (!decl.Func.IsPublic) { ParsingLog.AddWarning("Les fonctions contenues dans le block access doivent être publiques.", instruction.Line, instruction.Character, instruction.Source); } if (decl.Func.ReturnType.IsPrivateOrHasPrivateGenericArgs()) { ParsingLog.AddWarning("Les types de retour des déclaration de fonction du bloc access doivent être des types publics" + " et ne pas contenir de paramètre générique privé. (donné : " + decl.Func.ReturnType.GetFullName() + ")", instruction.Line, instruction.Character, instruction.Source); } // Vérification du return type. List <string> outReasons; if (!decl.Func.ReturnType.DoesSupportSerialization(out outReasons)) { string error; error = "Le type de retour de la fonction '" + decl.Func.GetFullName() + "' (" + decl.Func.ReturnType.GetFullName() + ") ne prend pas en charge la sérialisation. Raisons : "; error += Tools.StringUtils.Join(outReasons, ", ") + "."; ParsingLog.AddWarning(error, decl.Line, decl.Character, decl.Source); } // Vérification des types des arguments. foreach (Language.FunctionArgument arg in decl.Func.Arguments) { if (!arg.ArgType.DoesSupportSerialization(out outReasons)) { string error; error = "Le type de l'argument '" + arg.ArgName + "' (" + arg.ArgType + ") de la fonction " + decl.Func.GetFullName() + " ne prend pas en charge la sérialisation. Reasons : "; error += Tools.StringUtils.Join(outReasons, ", ") + "."; ParsingLog.AddWarning(error, decl.Line, decl.Character, decl.Source); } } Declarations.Add((Language.FunctionDeclaration)instruction); } else { ParsingLog.AddError("Instruction de type " + instruction.GetType().Name + " invalide dans un AccessBlock", instruction.Line, instruction.Character, instruction.Source ); } } }
/// <summary> /// Ajoute des déclarations à ce Container à partir d'un block. /// </summary> /// <param name="block"></param> public void AddDeclarationsFromScript(Language.NamedBlockDeclaration block, Semantic.TypeTable table) { foreach (Language.Instruction instruction in block.Instructions) { if (instruction is Language.NamedBlockDeclaration && ((Language.NamedBlockDeclaration)instruction).Name == Language.SemanticConstants.MacroBk) { AddDeclarationsFromMacroBlock((Language.NamedBlockDeclaration)instruction, table); } } }
/// <summary> /// Ajoute des déclarations à ce Container à partir d'un block Access. /// </summary> /// <param name="block"></param> void AddDeclarationsFromMacroBlock(Language.NamedBlockDeclaration block, Semantic.TypeTable table) { foreach (Language.Instruction instruction in block.Instructions) { if (instruction is Language.ClassDeclaration) { Language.ClassDeclaration classDecl = (Language.ClassDeclaration)instruction; MacroClass classMacro = new MacroClass(); // Récupération du type en language Clank.Core. Language.ClankType type = table.Types[classDecl.GetFullName()]; classMacro.Type = type; bool foundName = false; // Parse les instructions à la recherche de : // - une fonction Name qui retourne un string et qui contient des variables de type string // - d'autres fonctions qui ne contiennent que des variables de type string. foreach (Language.Instruction funcDeclInstruction in classDecl.Instructions) { Language.FunctionDeclaration funcDecl = funcDeclInstruction as Language.FunctionDeclaration; if (funcDecl != null) { if (funcDecl.Func.Name == "name") { // Nom de la classe foundName = true; classMacro.LanguageToTypeName = ParseLanguageTranslations(funcDecl); } else { // Ajout de la fonction. MacroFunction func = new MacroFunction(); func.Function = funcDecl.Func; func.LanguageToFunctionName = ParseLanguageTranslations(funcDecl); classMacro.Functions.Add(func.Function.GetFullName(), func); } } else if (funcDeclInstruction is Language.PlaceholderInstruction) { } else { ParsingLog.AddWarning("Seules les déclarations de fonctions sont autorisées dans les classes de block macro. Obtenu : " + funcDeclInstruction.GetType().Name + ".", instruction.Line, instruction.Character, instruction.Source); } } ClassDeclarations.Add(classMacro); // Erreur si pas de nom de classe trouvé : if (!foundName) { ParsingLog.AddError("Fonction 'string name()' attendue dans la déclaration de macro du type '" + type.Name + "'.", instruction.Line, instruction.Character, instruction.Source); } } else if (instruction is Language.FunctionDeclaration) { Language.FunctionDeclaration funcDecl = (Language.FunctionDeclaration)instruction; MacroFunction func = new MacroFunction(); func.Function = funcDecl.Func; func.LanguageToFunctionName = ParseLanguageTranslations(funcDecl); FunctionDeclarations.Add(func); } else { ParsingLog.AddWarning("Déclaration de classe attendue dans le block macro. Obtenu : " + instruction.GetType() + ".", instruction.Line, instruction.Character, instruction.Source); } } }