1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-14 22:34:09 +02:00

Reflection support for methods and types

This commit is contained in:
Brian Fiete 2020-05-28 07:36:34 -07:00
parent f1eafa8d81
commit be6a132fb5
4 changed files with 61 additions and 19 deletions

View file

@ -143,18 +143,7 @@ namespace System.Reflection
public Result<T> GetCustomAttribute<T>() where T : Attribute public Result<T> GetCustomAttribute<T>() where T : Attribute
{ {
if (mFieldData.mCustomAttributesIdx == -1) return mTypeInstance.[Friend]GetCustomAttribute<T>(mFieldData.mCustomAttributesIdx);
return .Err;
void* data = mTypeInstance.[Friend]mCustomAttrDataPtr[mFieldData.mCustomAttributesIdx];
T attrInst = ?;
switch (AttributeInfo.GetCustomAttribute(data, typeof(T), &attrInst))
{
case .Ok: return .Ok(attrInst);
default:
return .Err;
}
} }
void* GetDataPtrAndType(Object value, out Type type) void* GetDataPtrAndType(Object value, out Type type)

View file

@ -54,6 +54,12 @@ namespace System.Reflection
} }
} }
public this(TypeInstance typeInstance, TypeInstance.MethodData* methodData)
{
mTypeInstance = typeInstance;
mMethodData = methodData;
}
public Type GetParamType(int paramIdx) public Type GetParamType(int paramIdx)
{ {
Debug.Assert((uint)paramIdx < (uint)mMethodData.mParamCount); Debug.Assert((uint)paramIdx < (uint)mMethodData.mParamCount);
@ -66,10 +72,9 @@ namespace System.Reflection
return mMethodData.mParamData[paramIdx].mName; return mMethodData.mParamData[paramIdx].mName;
} }
public this(TypeInstance typeInstance, TypeInstance.MethodData* methodData) public Result<T> GetCustomAttribute<T>() where T : Attribute
{ {
mTypeInstance = typeInstance; return mTypeInstance.[Friend]GetCustomAttribute<T>(mMethodData.mCustomAttributesIdx);
mMethodData = methodData;
} }
public enum CallError public enum CallError

View file

@ -470,6 +470,13 @@ namespace System
return FieldInfo.Enumerator(null, bindingFlags); return FieldInfo.Enumerator(null, bindingFlags);
} }
public Result<T> GetCustomAttribute<T>() where T : Attribute
{
if (var typeInstance = this as TypeInstance)
return typeInstance.[Friend]GetCustomAttribute<T>(typeInstance.[Friend]mCustomAttributesIdx);
return .Err;
}
public struct Enumerator : IEnumerator<Type> public struct Enumerator : IEnumerator<Type>
{ {
int32 mCurId; int32 mCurId;
@ -731,6 +738,22 @@ namespace System.Reflection
{ {
return FieldInfo.Enumerator(this, bindingFlags); return FieldInfo.Enumerator(this, bindingFlags);
} }
Result<T> GetCustomAttribute<T>(int customAttributeIdx) where T : Attribute
{
if (customAttributeIdx == -1)
return .Err;
void* data = mCustomAttrDataPtr[customAttributeIdx];
T attrInst = ?;
switch (AttributeInfo.GetCustomAttribute(data, typeof(T), &attrInst))
{
case .Ok: return .Ok(attrInst);
default:
return .Err;
}
}
} }
[CRepr, AlwaysInclude(AssumeInstantiated=true)] [CRepr, AlwaysInclude(AssumeInstantiated=true)]

View file

@ -26,8 +26,21 @@ namespace Tests
[AttributeUsage(.Field)] [AttributeUsage(.Field)]
struct AttrBAttribute : Attribute struct AttrBAttribute : Attribute
{ {
int32 mA; public int32 mA;
float mB; public float mB;
public this(int32 a, float b)
{
mA = a;
mB = b;
}
}
[AttributeUsage(.Class | .Method, .ReflectAttribute)]
struct AttrCAttribute : Attribute
{
public int32 mA;
public float mB;
public this(int32 a, float b) public this(int32 a, float b)
{ {
@ -40,7 +53,7 @@ namespace Tests
[Reflect] [Reflect]
class ClassA class ClassA
{ {
[AlwaysInclude] [AlwaysInclude, AttrC(71, 72)]
static float StaticMethodA(int32 a, int32 b, float c) static float StaticMethodA(int32 a, int32 b, float c)
{ {
return a + b + c; return a + b + c;
@ -76,7 +89,7 @@ namespace Tests
} }
} }
[Reflect(.All)] [Reflect(.All), AttrC(1, 2)]
class ClassB class ClassB
{ {
[AttrA(11, 22, "StrA", "StrB")] [AttrA(11, 22, "StrA", "StrB")]
@ -127,6 +140,10 @@ namespace Tests
var result = methodInfo.Invoke(null, 100, (int32)20, 3.0f).Get(); var result = methodInfo.Invoke(null, 100, (int32)20, 3.0f).Get();
Test.Assert(result.Get<float>() == 123); Test.Assert(result.Get<float>() == 123);
result.Dispose(); result.Dispose();
let attrC = methodInfo.GetCustomAttribute<AttrCAttribute>().Get();
Test.Assert(attrC.mA == 71);
Test.Assert(attrC.mB == 72);
case 1: case 1:
Test.Assert(methodInfo.Name == "MemberMethodA"); Test.Assert(methodInfo.Name == "MemberMethodA");
var result = methodInfo.Invoke(ca, 100, (int32)20, 3.0f).Get(); var result = methodInfo.Invoke(ca, 100, (int32)20, 3.0f).Get();
@ -189,5 +206,13 @@ namespace Tests
fieldInfo.SetValue(cb, "DEF"); fieldInfo.SetValue(cb, "DEF");
Test.Assert(cb.mStr == "DEF"); Test.Assert(cb.mStr == "DEF");
} }
[Test]
static void TestC()
{
let attrC = typeof(ClassB).GetCustomAttribute<AttrCAttribute>().Get();
Test.Assert(attrC.mA == 1);
Test.Assert(attrC.mB == 2);
}
} }
} }