using CppAst; namespace refl { internal class FieldData { public string Name { get; set; } public string Meta { get; set; } public FieldData(string name, string meta) { Name = name; Meta = meta; } } internal class FieldMeta { public List MemberList { get; set; } public List MethodList { get; set; } public FieldMeta() { MemberList = new List(); MethodList = new List(); } } internal class ClassMeta { public string Name { get; set; } public string ParentName { get; set; } public string Path { get; set; } public Dictionary Fields { get; set; } public ClassMeta(string name, string parentName) { Name = name; ParentName = parentName; Path = ""; Fields = new Dictionary(); } } internal class ModuleMeta { public static HashSet NameSet = new HashSet(); public string NameSpace { get; set; } public List ClassList; public List ChildList; public ModuleMeta(string name_space) { NameSpace = name_space; ClassList = new List(); ChildList = new List(); } public bool HasMeta() { return ClassList.Count > 0 || ChildList.Count > 0; } public static ClassMeta ParseCppClass(CppClass cppClass) { string parentName = "void"; if (cppClass.BaseTypes.Count == 1) { var type = cppClass.BaseTypes[0].Type; CppClass? parent = type as CppClass; if (parent != null) { parentName = parent.Name; } } ClassMeta cls_meta = new ClassMeta(cppClass.Name, parentName); foreach (var field in cppClass.Fields) { if (field.Attributes.Count == 0) continue; foreach (var attribute in field.Attributes) { var attr_metas = MetaToken.ParseMeta(attribute.Arguments); foreach (var pair in attr_metas) { if (!cls_meta.Fields.ContainsKey(pair.Key)) { cls_meta.Fields.Add(pair.Key, new FieldMeta()); } cls_meta.Fields[pair.Key].MemberList.Add(new FieldData(field.Name, pair.Value)); } } } foreach (var func in cppClass.Functions) { if (func.Attributes.Count == 0) continue; foreach (var attribute in func.Attributes) { var attr_metas = MetaToken.ParseMeta(attribute.Arguments); foreach (var pair in attr_metas) { if (!cls_meta.Fields.ContainsKey(pair.Key)) { cls_meta.Fields.Add(pair.Key, new FieldMeta()); } cls_meta.Fields[pair.Key].MethodList.Add(new FieldData(func.Name, pair.Value)); } } } return cls_meta; } public static ModuleMeta ParseCppNamespaces(CppNamespace cpp) { var module = new ModuleMeta(cpp.Name); foreach (var cppClass in cpp.Classes) { var cls_meta = ParseCppClass(cppClass); if(cls_meta.Fields.Count > 0) { module.ClassList.Add(cls_meta); } } foreach (var spaces in cpp.Namespaces) { var child = ParseCppNamespaces(spaces); module.ChildList.Add(child); } return module; } public static ModuleMeta ParseCompileInfo(CppCompilation cpp) { var module = new ModuleMeta(""); foreach (var cppClass in cpp.Classes) { var cls_meta = ParseCppClass(cppClass); module.ClassList.Add(cls_meta); } foreach(var spaces in cpp.Namespaces) { var child = ParseCppNamespaces(spaces); module.ChildList.Add(child); } ParseMetaName(module); return module; } public static void ParseMetaName(ModuleMeta module) { ParseClassMetaName(module); foreach(var child in module.ChildList) { ParseMetaName(child); } } public static void ParseClassMetaName(ModuleMeta module) { foreach(var cls in module.ClassList) { foreach(var field in cls.Fields) { if (!NameSet.Contains(field.Key)) { NameSet.Add(field.Key); } } } } } }