using CommandLine; using CppAst; namespace refl { [Verb("build",HelpText = "Generate custom code based on the parsed AST.")] internal class CmdBuildOption { [Value(0, MetaName = "", Required = true, Min = 2, HelpText = "Input file(s) for parsing.")] public IEnumerable? InputFiles { get; set; } [Option('o', "output", Required = true, HelpText = "Output file for generated code.")] public string Output { get; set; } = ""; [Option('t', "template", Required = true, HelpText = "the code template need to render")] public string Template { get; set; } = ""; [Option('i', "include", Required = false, HelpText = "link to the include dir")] public string IncludeDir { get; set; } = ""; [Option('d', "define", Required = false, HelpText = "define a macro on the command line")] public string Define { get; set; } = ""; [Option('v', "verbose", Required = false, HelpText = "output compile info")] public bool Verbose { get; set; } = false; [Option('h', "help", HelpText = "Display this help message.")] public bool Help { get; set; } = false; static CppParserOptions MakeParserOptions(CmdBuildOption opt) { var parse = new CppParserOptions { AdditionalArguments = { "-std=c++20" }, //ParseTokenAttributes = true, //ParseCommentAttribute = true, }; if (!string.IsNullOrWhiteSpace(opt.Define)) { var defines = opt.Define.Split(";"); foreach (var def in defines) { parse.Defines.Add(def); } } if (!string.IsNullOrWhiteSpace(opt.IncludeDir)) { var links = opt.IncludeDir.Split(";"); foreach (var ink in links) { parse.IncludeFolders.Add(ink); } } return parse; } public static int CMD_CheckBuildOption(CmdBuildOption opt) { if(opt.InputFiles == null || !ClassMetaGen.InitTemplate(opt.Template)) { return -1; } var parse_opt = MakeParserOptions(opt); var compilation = CppAst.CppParser.ParseFiles(opt.InputFiles.Skip(1).ToList(), parse_opt); if (opt.Verbose) { // Print diagnostic messages foreach (var message in compilation.Diagnostics.Messages) if (message.Type.Equals(CppLogMessageType.Error)) Console.WriteLine(message); } var module = ModuleMeta.ParseCompileInfo(compilation); ClassMetaGen.GenCppMeta(module, opt.Output.ToLower()); if (opt.Verbose) { Console.WriteLine("gen success!"); } return 0; } } }