diff --git a/src/refl/BuildOption.cs b/src/refl/BuildOption.cs index 12ca8b0..dc029e8 100644 --- a/src/refl/BuildOption.cs +++ b/src/refl/BuildOption.cs @@ -60,29 +60,7 @@ namespace refl foreach (var message in compilation.Diagnostics.Messages) if(message.Type.Equals(CppLogMessageType.Error)) Console.WriteLine(message); - // Print all classes, structs - foreach (var cppClass in compilation.Classes) - { - Console.WriteLine(cppClass); - foreach(var field in cppClass.Fields) - { - if (field.Attributes.Count == 0) - continue; - foreach(var attribute in field.Attributes) - { - Console.WriteLine(attribute.Arguments); - } - } - foreach(var func in cppClass.Functions) - { - if (func.Attributes.Count == 0) - continue; - foreach (var attribute in func.Attributes) - { - Console.WriteLine(attribute.Arguments); - } - } - } + ModuleMeta.ParseCompileInfo(compilation); return 0; } } diff --git a/src/refl/ClassMeta.cs b/src/refl/ClassMeta.cs new file mode 100644 index 0000000..8ddf76a --- /dev/null +++ b/src/refl/ClassMeta.cs @@ -0,0 +1,169 @@ +using CppAst; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +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 Path { get; set; } + + public Dictionary Fields { get; set; } + + public ClassMeta(string name) + { + Name = name; + 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) + { + ClassMeta cls_meta = new ClassMeta(cppClass.Name); + 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); + } + } + } + } + } + } +} diff --git a/src/refl/ClassMetaGen.cs b/src/refl/ClassMetaGen.cs new file mode 100644 index 0000000..72954d7 --- /dev/null +++ b/src/refl/ClassMetaGen.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace refl +{ + internal class ClassMetaGen + { + public static Dictionary FileList = new Dictionary(); + public static void GenCppMeta(ModuleMeta module) + { + foreach(var pair in ModuleMeta.NameMaps) + { + FileList.Add(pair.Key, new StringBuilder()); + } + foreach(var cls in module.ClassList) + { + + } + } + public static void GenClassMeta(ModuleMeta module) + { + foreach (var cls in module.ClassList) + { + foreach (var field in cls.Fields) + { + + } + } + } + } +} diff --git a/src/refl/MetaToken.cs b/src/refl/MetaToken.cs new file mode 100644 index 0000000..bcceaf0 --- /dev/null +++ b/src/refl/MetaToken.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +namespace refl +{ + internal class MetaToken + { + enum State + { + Start, + Key, + Value + } + // 判断左右括号是否匹配的辅助方法 + static bool IsMatching(char left, char right) + { + return (left == '(' && right == ')') || + (left == '[' && right == ']') || + (left == '{' && right == '}'); + } + public static Dictionary ParseMeta(string line) + { + State state = State.Start; + StringBuilder key = new StringBuilder(); + StringBuilder value = new StringBuilder(); + Stack stack = new Stack(); + Dictionary metas = new Dictionary(); + foreach (char c in line) + { + switch (state) + { + case State.Start: + if (!char.IsWhiteSpace(c)) + { + key.Append(c); + state = State.Key; + } + break; + case State.Key: + if(c == '=') + { + state = State.Value; + } + else + { + key.Append(c); + } + break; + case State.Value: + if (stack.Count == 0 && (c == ',' || c == '\n')) + { + metas.Add(key.ToString().Trim(), value.ToString().Trim()); + key.Clear(); + value.Clear(); + state = State.Start; + break; + } + value.Append(c); + if(c == '(' || c == '{' || c == '[') + { + stack.Push(c); + }else if(stack.Count > 0 && IsMatching(stack.Peek(), c)) + { + stack.Pop(); + } + if(c == '"') + { + if(stack.Count > 0 && stack.Peek() == c) + { + stack.Pop(); + } + else + { + stack.Push(c); + } + } + break; + } + } + if(key.Length > 0 && value.Length > 0) + { + metas.Add(key.ToString().Trim(), value.ToString().Trim()); + } + return metas; + } + } +} diff --git a/src/refl/cpp/vertex.h b/src/refl/cpp/vertex.h index d49f162..e3138ad 100644 --- a/src/refl/cpp/vertex.h +++ b/src/refl/cpp/vertex.h @@ -1,43 +1,46 @@ #include using namespace std; -struct vec3_parent { - virtual int norm(int x1, int& x2) { - x2 = x1 * x2; - return x2; - //cout << x2 << "vec3_parent::norm" << endl; - } -}; -struct vec3_Meta; -struct vec3 : public vec3_parent { - using MyMeta = vec3_Meta; - __cppast(Meta = { 0.f}, UIMeta = {1.f}) - float x = 1; - __cppast(Meta = { 0.f}) - float y = 2; - __cppast(Meta = { 0.f}) - float z = 3; - string name{ "hellohellohellohellohellohello" }; - __cppast(Meta = { {3,4} }) - int norm(int x1, int& x2)override { - int tmp = x1 * 2 + 1; - x1 = x2; - x2 = tmp; - return x2; - //cout << x2 << "vec3::norm" << endl; - } - virtual float norm1(int& x1) { - x1 = x1 * x * y * z; - //x = x1; - //y = x1 - 1; - //z = x1 - 10; - //cout << x1 << "::norm1" << endl; - return x1; - } - static void norm2(int x1 = 10) { - cout << x1 << "::norm2" << endl; - } - static void norm3(int x1 = 10) { - x1 = x1 * 10; - cout << x1 << "::norm3" << endl; - } -}; \ No newline at end of file +namespace test{ + struct vec3_parent { + virtual int norm(int x1, int& x2) { + x2 = x1 * x2; + return x2; + //cout << x2 << "vec3_parent::norm" << endl; + } + }; + struct vec3_Meta; + struct vec3 : public vec3_parent { + using MyMeta = vec3_Meta; + __cppast(Meta = { 0.f}, UIMeta = {1.f}) + float x = 1; + __cppast(Meta = { 0.f}) + float y = 2; + __cppast(Meta = { 0.f}) + float z = 3; + string name{ "hellohellohellohellohellohello" }; + __cppast(Meta = { {3,4} }) + int norm(int x1, int& x2)override { + int tmp = x1 * 2 + 1; + x1 = x2; + x2 = tmp; + return x2; + //cout << x2 << "vec3::norm" << endl; + } + virtual float norm1(int& x1) { + x1 = x1 * x * y * z; + //x = x1; + //y = x1 - 1; + //z = x1 - 10; + //cout << x1 << "::norm1" << endl; + return x1; + } + static void norm2(int x1 = 10) { + cout << x1 << "::norm2" << endl; + } + static void norm3(int x1 = 10) { + x1 = x1 * 10; + cout << x1 << "::norm3" << endl; + } + }; +} +#include "meta.vertex.inl" \ No newline at end of file diff --git a/src/refl/template/refl.cpp b/src/refl/template/refl.cpp index ec61894..bfd110e 100644 --- a/src/refl/template/refl.cpp +++ b/src/refl/template/refl.cpp @@ -1,5 +1,4 @@ #include "vertex.h" -#include "vertex.generated.h" struct vec3_Static_Meta { //这里好像不需要