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 Dictionary> NameMaps = new Dictionary>(); 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 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); } ParseNameMap(module); return module; } public static void ParseNameMap(ModuleMeta module) { ParseClassNameMap(module); foreach(var child in module.ChildList) { ParseNameMap(child); } } public static void ParseClassNameMap(ModuleMeta module) { foreach(var cls in module.ClassList) { foreach(var field in cls.Fields) { if (!NameMaps.ContainsKey(field.Key)) { NameMaps.Add(field.Key, new HashSet()); } var nameList = NameMaps[field.Key]; foreach(var member in field.Value.MemberList) { if (!nameList.Contains(member.Name)) { nameList.Add(member.Name); } } foreach (var method in field.Value.MethodList) { if (!nameList.Contains(method.Name)) { nameList.Add(method.Name); } } } } } } }