diff --git a/BeefLibs/corlib/src/Reflection/FieldInfo.bf b/BeefLibs/corlib/src/Reflection/FieldInfo.bf index b605cefa..b3dd2ddc 100644 --- a/BeefLibs/corlib/src/Reflection/FieldInfo.bf +++ b/BeefLibs/corlib/src/Reflection/FieldInfo.bf @@ -143,18 +143,7 @@ namespace System.Reflection public Result GetCustomAttribute() where T : Attribute { - if (mFieldData.mCustomAttributesIdx == -1) - 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; - } + return mTypeInstance.[Friend]GetCustomAttribute(mFieldData.mCustomAttributesIdx); } void* GetDataPtrAndType(Object value, out Type type) diff --git a/BeefLibs/corlib/src/Reflection/MethodInfo.bf b/BeefLibs/corlib/src/Reflection/MethodInfo.bf index aa8ed75e..f26d907e 100644 --- a/BeefLibs/corlib/src/Reflection/MethodInfo.bf +++ b/BeefLibs/corlib/src/Reflection/MethodInfo.bf @@ -54,6 +54,12 @@ namespace System.Reflection } } + public this(TypeInstance typeInstance, TypeInstance.MethodData* methodData) + { + mTypeInstance = typeInstance; + mMethodData = methodData; + } + public Type GetParamType(int paramIdx) { Debug.Assert((uint)paramIdx < (uint)mMethodData.mParamCount); @@ -66,10 +72,9 @@ namespace System.Reflection return mMethodData.mParamData[paramIdx].mName; } - public this(TypeInstance typeInstance, TypeInstance.MethodData* methodData) + public Result GetCustomAttribute() where T : Attribute { - mTypeInstance = typeInstance; - mMethodData = methodData; + return mTypeInstance.[Friend]GetCustomAttribute(mMethodData.mCustomAttributesIdx); } public enum CallError diff --git a/BeefLibs/corlib/src/Type.bf b/BeefLibs/corlib/src/Type.bf index 31a6ba04..4704e638 100644 --- a/BeefLibs/corlib/src/Type.bf +++ b/BeefLibs/corlib/src/Type.bf @@ -470,6 +470,13 @@ namespace System return FieldInfo.Enumerator(null, bindingFlags); } + public Result GetCustomAttribute() where T : Attribute + { + if (var typeInstance = this as TypeInstance) + return typeInstance.[Friend]GetCustomAttribute(typeInstance.[Friend]mCustomAttributesIdx); + return .Err; + } + public struct Enumerator : IEnumerator { int32 mCurId; @@ -731,6 +738,22 @@ namespace System.Reflection { return FieldInfo.Enumerator(this, bindingFlags); } + + Result GetCustomAttribute(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)] diff --git a/IDEHelper/Tests/src/Reflection.bf b/IDEHelper/Tests/src/Reflection.bf index 56b27653..0dd2f5a7 100644 --- a/IDEHelper/Tests/src/Reflection.bf +++ b/IDEHelper/Tests/src/Reflection.bf @@ -26,8 +26,21 @@ namespace Tests [AttributeUsage(.Field)] struct AttrBAttribute : Attribute { - int32 mA; - float mB; + public int32 mA; + 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) { @@ -40,7 +53,7 @@ namespace Tests [Reflect] class ClassA { - [AlwaysInclude] + [AlwaysInclude, AttrC(71, 72)] static float StaticMethodA(int32 a, int32 b, float c) { return a + b + c; @@ -76,7 +89,7 @@ namespace Tests } } - [Reflect(.All)] + [Reflect(.All), AttrC(1, 2)] class ClassB { [AttrA(11, 22, "StrA", "StrB")] @@ -127,6 +140,10 @@ namespace Tests var result = methodInfo.Invoke(null, 100, (int32)20, 3.0f).Get(); Test.Assert(result.Get() == 123); result.Dispose(); + + let attrC = methodInfo.GetCustomAttribute().Get(); + Test.Assert(attrC.mA == 71); + Test.Assert(attrC.mB == 72); case 1: Test.Assert(methodInfo.Name == "MemberMethodA"); var result = methodInfo.Invoke(ca, 100, (int32)20, 3.0f).Get(); @@ -189,5 +206,13 @@ namespace Tests fieldInfo.SetValue(cb, "DEF"); Test.Assert(cb.mStr == "DEF"); } + + [Test] + static void TestC() + { + let attrC = typeof(ClassB).GetCustomAttribute().Get(); + Test.Assert(attrC.mA == 1); + Test.Assert(attrC.mB == 2); + } } }