214 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			214 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using CppAst;
 | 
						|
using Irony;
 | 
						|
using static System.Net.Mime.MediaTypeNames;
 | 
						|
using static System.Runtime.InteropServices.JavaScript.JSType;
 | 
						|
 | 
						|
namespace refl
 | 
						|
{
 | 
						|
    internal class FieldData
 | 
						|
    {
 | 
						|
        public string Name { get; set; }
 | 
						|
        public string Meta { get; set; }
 | 
						|
        public string Ref { get; set; }
 | 
						|
        //public Dictionary<string, string> UserMeta = new Dictionary<string, string>();
 | 
						|
        public FieldData(string name, string meta)
 | 
						|
        {
 | 
						|
            Name = name;
 | 
						|
            Meta = "{" + meta + "}";
 | 
						|
            Ref = "";
 | 
						|
        }
 | 
						|
 | 
						|
    }
 | 
						|
    internal class FieldMeta
 | 
						|
    {
 | 
						|
        public List<FieldData> MemberList { get; set; }
 | 
						|
        public List<FieldData> MethodList { get; set; }
 | 
						|
        public List<FieldData> CtorList { get; set; }
 | 
						|
        public FieldMeta()
 | 
						|
        {
 | 
						|
            MemberList = new List<FieldData>();
 | 
						|
            MethodList = new List<FieldData>();
 | 
						|
            CtorList = new List<FieldData>();
 | 
						|
        }
 | 
						|
    }
 | 
						|
    internal class ClassMeta
 | 
						|
    {
 | 
						|
        public string Name { get; set; }
 | 
						|
        public string ParentName { get; set; }
 | 
						|
        public string Path { get; set; }
 | 
						|
 | 
						|
        public Dictionary<string, FieldMeta> Fields { get; set; }
 | 
						|
        public ClassMeta(string name, string parentName)
 | 
						|
        {
 | 
						|
            Name = name;
 | 
						|
            ParentName = parentName;
 | 
						|
            Path = "";
 | 
						|
            Fields = new Dictionary<string, FieldMeta>();
 | 
						|
        }
 | 
						|
    }
 | 
						|
    internal class ModuleMeta
 | 
						|
    {
 | 
						|
        public static HashSet<string> NameSet = new HashSet<string>();
 | 
						|
        public string NameSpace { get; set; }
 | 
						|
        public List<ClassMeta> ClassList;
 | 
						|
        public List<ModuleMeta> ChildList;
 | 
						|
 | 
						|
        public static OverTree OverData = new OverTree();
 | 
						|
        public ModuleMeta(string name_space)
 | 
						|
        {
 | 
						|
            NameSpace = name_space;
 | 
						|
            ClassList = new List<ClassMeta>();
 | 
						|
            ChildList = new List<ModuleMeta>();
 | 
						|
        }
 | 
						|
        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);
 | 
						|
            OverData.Clear();
 | 
						|
            foreach (var field in cppClass.Fields)
 | 
						|
            {
 | 
						|
                if (field.Attributes.Count == 0)
 | 
						|
                    continue;
 | 
						|
                foreach (var attribute in field.Attributes)
 | 
						|
                {
 | 
						|
                    string key, value;
 | 
						|
                    MetaToken.ParseMeta(attribute.Arguments, out key, out value);
 | 
						|
                    if (!cls_meta.Fields.ContainsKey(key))
 | 
						|
                    {
 | 
						|
                        cls_meta.Fields.Add(key, new FieldMeta());
 | 
						|
                    }
 | 
						|
                    cls_meta.Fields[key].MemberList.Add(new FieldData(field.Name, value));
 | 
						|
                }
 | 
						|
            }
 | 
						|
            foreach (var func in cppClass.Constructors)
 | 
						|
            {
 | 
						|
                if (func.Attributes.Count == 0)
 | 
						|
                    continue;
 | 
						|
                foreach (var attribute in func.Attributes)
 | 
						|
                {
 | 
						|
                    string key, value;
 | 
						|
                    string? next;
 | 
						|
                    MetaToken.ParseAllMeta(attribute.Arguments, out key, out value, out next);
 | 
						|
                    FieldData data = new FieldData(key, value);
 | 
						|
                    if (!cls_meta.Fields.ContainsKey(key))
 | 
						|
                    {
 | 
						|
                        cls_meta.Fields.Add(key, new FieldMeta());
 | 
						|
                    }
 | 
						|
                    cls_meta.Fields[key].CtorList.Add(data);
 | 
						|
                    ParseClassUserMeta(cppClass, data, next);
 | 
						|
                }
 | 
						|
            }
 | 
						|
            foreach (var func in cppClass.Functions)
 | 
						|
            {
 | 
						|
                if (func.Attributes.Count == 0)
 | 
						|
                    continue;
 | 
						|
                foreach (var attribute in func.Attributes)
 | 
						|
                {
 | 
						|
                    string key, value;
 | 
						|
                    string? next;
 | 
						|
                    MetaToken.ParseAllMeta(attribute.Arguments, out key, out value, out next);
 | 
						|
                    FieldData data = new FieldData(func.Name, value);
 | 
						|
                    if (!cls_meta.Fields.ContainsKey(key))
 | 
						|
                    {
 | 
						|
                        cls_meta.Fields.Add(key, new FieldMeta());
 | 
						|
                    }
 | 
						|
                    cls_meta.Fields[key].MethodList.Add(data);
 | 
						|
                    ParseClassUserMeta(cppClass, data, next);
 | 
						|
                }
 | 
						|
            }
 | 
						|
            return cls_meta;
 | 
						|
        }
 | 
						|
        public static void ParseClassUserMeta(CppClass cppClass, FieldData data, string? next)
 | 
						|
        {
 | 
						|
            if (next == null)
 | 
						|
                return;
 | 
						|
            OverData.Init(cppClass);
 | 
						|
            string key, value;
 | 
						|
            while (next != null)
 | 
						|
            {
 | 
						|
                MetaToken.ParseAllMeta(next, out key, out value, out next);
 | 
						|
                if (key == "ref")
 | 
						|
                {
 | 
						|
                    value = OverData.Find(value.Trim());
 | 
						|
                    data.Ref = value;
 | 
						|
                }
 | 
						|
                //data.UserMeta.Add(key, value);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        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);
 | 
						|
                if (child.ClassList.Count > 0 || child.ChildList.Count > 0)
 | 
						|
                {
 | 
						|
                    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);
 | 
						|
                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);
 | 
						|
            }
 | 
						|
            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);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |