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 ClassMetaData data = new ClassMetaData(); private GenMeta meta = new GenMeta(); private GenMetaImpl metaImpl = new GenMetaImpl(); private GenMultyMeta multyMeta = new GenMultyMeta(); private Stack nameSpaces = new Stack(); public Gen() { } public static string PreprocessTemplate(string template, string indent, string newline) { // 替换占位符 return template.Replace("{{ Indent }}", indent); } public static bool InitTemplate(string dir) { string meta_file = Path.Combine(dir, "meta.liquid"); string meta_impl_file = Path.Combine(dir, "meta_impl.liquid"); string multy_meta_file = Path.Combine(dir, "multy_meta.liquid"); var parser = new FluidParser(); return GenMeta.InitTemplate(meta_file, parser) && GenMetaImpl.InitTemplate(meta_impl_file, parser) && GenMultyMeta.InitTemplate(multy_meta_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"); Meta.AppendLine("namespace refl_impl{"); foreach (var name in ModuleMeta.NameSet) { var build = new StringBuilder(); build.AppendLine("#pragma once"); build.AppendLine("namespace refl_impl{"); 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) { Meta.AppendLine("\r\n"); Output.AppendLine("}\r\n"); foreach (var pair in FileList) { string path = $"{pair.Key}_{file_name}".ToLower(); if (dir != null) { path = Path.Combine(dir, path); } pair.Value.AppendLine("}\r\n"); 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, ClassMetaData data) { string fullName = GenPrefix() + cls.Name; data.FullName = fullName; bool isMulty = meta.GenClassMeta(cls, data); Meta.Append(metaImpl.GenClassMeta(cls, fullName, isMulty)); Meta.AppendLine(""); if (isMulty) { var res = multyMeta.GenClassMeta(cls, fullName); Output.Append(res); Output.AppendLine(""); } } } }