using Fluid; using Microsoft.Extensions.Primitives; using System.IO; using System.Text; using System.Xml.Linq; namespace refl { internal class Gen { public static Dictionary FileList = new Dictionary(); public static StringBuilder Meta = new StringBuilder(); public static StringBuilder Output = new StringBuilder(); private ClassMetaImplData data = new ClassMetaImplData(); private GenMeta meta = new GenMeta(); private GenMetaImpl metaImpl = new GenMetaImpl(); private Stack nameSpaces = new Stack(); public Gen() { } public static bool InitTemplate(string dir) { string meta_file = Path.Combine(dir, "meta.liquid"); string meta_impl_file = Path.Combine(dir, "meta_impl.liquid"); var parser = new FluidParser(); return GenMeta.InitTemplate(meta_file, parser) && GenMetaImpl.InitTemplate(meta_impl_file, parser); } public void CheckDir(string? dir) { if (dir != null && !Directory.Exists(dir)) { Directory.CreateDirectory(dir); } } public void InitFile(string file_name) { Meta.AppendLine("#pragma once"); foreach (var name in ModuleMeta.NameSet) { var build = new StringBuilder(); build.AppendLine("#pragma once"); FileList.Add(name, build); } } public void GenCppMeta(ModuleMeta module, string target) { string file_name = Path.GetFileName(target); string? dir = Path.GetDirectoryName(target); CheckDir(dir); InitFile(file_name); GenModuleMeta(module, null); OutFile(file_name, dir, target); } public void OutFile(string file_name, string? dir,string target) { foreach (var pair in FileList) { string path = $"{pair.Key}_{file_name}".ToLower(); if (dir != null) { path = Path.Combine(dir, path); } File.WriteAllText(path, pair.Value.ToString()); if (pair.Key == "Meta") { path = $"Meta_{file_name}".ToLower(); Output.AppendLine($"#include \"{path}\""); } } using (StreamWriter writer = new StreamWriter(target, false, Encoding.UTF8)) { writer.Write(Meta.ToString()); writer.Write(Output.ToString()); } } public void GenModuleMeta(ModuleMeta module, string? prefix) { if (!module.HasMeta()) { return; } if (prefix != null) { nameSpaces.Push(module.NameSpace); } foreach (var cls in module.ClassList) { GenClassMeta(cls, data); } string new_prefix = prefix == null ? "" : "\t"; foreach (var child in module.ChildList) { GenModuleMeta(child, new_prefix); } if (prefix != null) { nameSpaces.Pop(); } } public string GenPrefix() { if (nameSpaces.Count > 0) { return string.Join("::", nameSpaces) + "::"; } return ""; } public void GenClassMeta(ClassMeta cls, ClassMetaImplData data) { string fullName = GenPrefix() + cls.Name; data.FullName = fullName; bool isMulty = metaImpl.GenClassMeta(cls, data); Meta.Append(meta.GenClassMeta(cls, fullName, isMulty)); Meta.AppendLine(""); } } }