This commit is contained in:
ouczbs 2024-04-20 18:02:20 +08:00
parent 379dfa2166
commit 310b0da3de
6 changed files with 339 additions and 65 deletions

View File

@ -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;
}
}

169
src/refl/ClassMeta.cs Normal file
View File

@ -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<FieldData> MemberList { get; set; }
public List<FieldData> MethodList { get; set; }
public FieldMeta()
{
MemberList = new List<FieldData>();
MethodList = new List<FieldData>();
}
}
internal class ClassMeta
{
public string Name { get; set; }
public string Path { get; set; }
public Dictionary<string, FieldMeta> Fields { get; set; }
public ClassMeta(string name)
{
Name = name;
Path = "";
Fields = new Dictionary<string, FieldMeta>();
}
}
internal class ModuleMeta
{
public static Dictionary<string, HashSet<string>> NameMaps = new Dictionary<string, HashSet<string>>();
public string NameSpace { get; set; }
public List<ClassMeta> ClassList;
public List<ModuleMeta> ChildList;
public ModuleMeta(string name_space)
{
NameSpace = name_space;
ClassList = new List<ClassMeta>();
ChildList = new List<ModuleMeta>();
}
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<string>());
}
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);
}
}
}
}
}
}
}

35
src/refl/ClassMetaGen.cs Normal file
View File

@ -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<string, StringBuilder> FileList = new Dictionary<string, StringBuilder>();
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)
{
}
}
}
}
}

90
src/refl/MetaToken.cs Normal file
View File

@ -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<string,string> ParseMeta(string line)
{
State state = State.Start;
StringBuilder key = new StringBuilder();
StringBuilder value = new StringBuilder();
Stack<char> stack = new Stack<char>();
Dictionary<string,string> metas = new Dictionary<string, string>();
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;
}
}
}

View File

@ -1,43 +1,46 @@
#include <iostream>
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;
}
};
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"

View File

@ -1,5 +1,4 @@
#include "vertex.h"
#include "vertex.generated.h"
struct vec3_Static_Meta {
//这里好像不需要