From c10565678ebedf7bfc237e25ae9f661ed98a03c2 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Tue, 6 Jul 2021 10:55:38 -0700 Subject: [PATCH] Reflection support for method param attributes, return attributes --- BeefLibs/corlib/src/Reflection/MethodInfo.bf | 11 ++++++ BeefLibs/corlib/src/Type.bf | 2 ++ IDE/mintest/minlib/src/System/Type.bf | 2 ++ IDEHelper/Compiler/BfModule.cpp | 37 ++++++++++++-------- 4 files changed, 38 insertions(+), 14 deletions(-) diff --git a/BeefLibs/corlib/src/Reflection/MethodInfo.bf b/BeefLibs/corlib/src/Reflection/MethodInfo.bf index 14397d13..7adbe688 100644 --- a/BeefLibs/corlib/src/Reflection/MethodInfo.bf +++ b/BeefLibs/corlib/src/Reflection/MethodInfo.bf @@ -37,11 +37,22 @@ namespace System.Reflection return mMethodData.mParamData[paramIdx].mName; } + public Result GetParamCustomAttribute(int paramIdx) where T : Attribute + { + Debug.Assert((uint)paramIdx < (uint)mMethodData.mParamCount); + return mTypeInstance.[Friend]GetCustomAttribute(mMethodData.mParamData[paramIdx].mCustomAttributesIdx); + } + public Result GetCustomAttribute() where T : Attribute { return mTypeInstance.[Friend]GetCustomAttribute(mMethodData.mCustomAttributesIdx); } + public Result GetReturnCustomAttribute() where T : Attribute + { + return mTypeInstance.[Friend]GetCustomAttribute(mMethodData.mReturnCustomAttributesIdx); + } + public enum CallError { case None; diff --git a/BeefLibs/corlib/src/Type.bf b/BeefLibs/corlib/src/Type.bf index d8b60c6c..d12cd3c6 100644 --- a/BeefLibs/corlib/src/Type.bf +++ b/BeefLibs/corlib/src/Type.bf @@ -718,6 +718,7 @@ namespace System.Reflection public int32 mMethodIdx; public int32 mVirtualIdx; public int32 mCustomAttributesIdx; + public int32 mReturnCustomAttributesIdx; } public enum ParamFlags : int16 @@ -734,6 +735,7 @@ namespace System.Reflection public TypeId mType; public ParamFlags mParamFlags; public int32 mDefaultIdx; + public int32 mCustomAttributesIdx; } public struct InterfaceData diff --git a/IDE/mintest/minlib/src/System/Type.bf b/IDE/mintest/minlib/src/System/Type.bf index 22804438..0392f154 100644 --- a/IDE/mintest/minlib/src/System/Type.bf +++ b/IDE/mintest/minlib/src/System/Type.bf @@ -679,6 +679,7 @@ namespace System.Reflection public int32 mMethodIdx; public int32 mVirtualIdx; public int32 mCustomAttributesIdx; + public int32 mReturnCustomAttributesIdx; } public enum ParamFlags : int16 @@ -695,6 +696,7 @@ namespace System.Reflection public TypeId mType; public ParamFlags mParamFlags; public int32 mDefaultIdx; + public int32 mCustomAttributesIdx; } public struct InterfaceData diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 294073e5..bbf6ad94 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -6501,7 +6501,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin struct _SortedMethodInfo { BfMethodDef* mMethodDef; - BfCustomAttributes* mMethodCustomAttributes; + BfMethodCustomAttributes* mMethodCustomAttributes; }; Array<_SortedMethodInfo> sortedMethodList; @@ -6542,10 +6542,10 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin bool includeMethod = reflectIncludeAllMethods; - BfCustomAttributes* methodCustomAttributes = NULL; + BfMethodCustomAttributes* methodCustomAttributes = NULL; if ((defaultMethod->mMethodInfoEx != NULL) && (defaultMethod->mMethodInfoEx->mMethodCustomAttributes != NULL) && (defaultMethod->mMethodInfoEx->mMethodCustomAttributes->mCustomAttributes != NULL)) { - methodCustomAttributes = defaultMethod->mMethodInfoEx->mMethodCustomAttributes->mCustomAttributes; + methodCustomAttributes = defaultMethod->mMethodInfoEx->mMethodCustomAttributes; for (auto& customAttr : defaultMethod->mMethodInfoEx->mMethodCustomAttributes->mCustomAttributes->mAttributes) { if (customAttr.mType->mTypeDef->mName->ToString() == "ReflectAttribute") @@ -6643,7 +6643,13 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin BfMethodFlags methodFlags = defaultMethod->GetMethodFlags(); - int customAttrIdx = _HandleCustomAttrs(methodInfo.mMethodCustomAttributes); + int customAttrIdx = -1; + int returnCustomAttrIdx = -1; + if (methodInfo.mMethodCustomAttributes != NULL) + { + customAttrIdx = _HandleCustomAttrs(methodInfo.mMethodCustomAttributes->mCustomAttributes); + returnCustomAttrIdx = _HandleCustomAttrs(methodInfo.mMethodCustomAttributes->mReturnCustomAttributes); + } enum ParamFlags { @@ -6664,13 +6670,18 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin BfIRValue paramNameConst = GetStringObjectValue(paramName, !mIsComptimeModule); + int paramCustomAttrIdx = -1; + if ((methodInfo.mMethodCustomAttributes != NULL) && (paramIdx < (int)methodInfo.mMethodCustomAttributes->mParamCustomAttributes.mSize)) + paramCustomAttrIdx = _HandleCustomAttrs(methodInfo.mMethodCustomAttributes->mParamCustomAttributes[paramIdx]); + SizedArray paramDataVals = { emptyValueType, paramNameConst, GetConstValue(paramType->mTypeId, typeIdType), GetConstValue((int32)paramFlags, shortType), - GetConstValue(customAttrIdx, intType) // defaultIdx + GetConstValue(-1, intType), // defaultIdx + GetConstValue(paramCustomAttrIdx, intType) // customAttrIdx }; auto paramData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapType(reflectParamDataType, BfIRPopulateType_Full), paramDataVals); paramVals.Add(paramData); @@ -6739,6 +6750,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin GetConstValue(methodIdx, intType), GetConstValue(vDataVal, intType), GetConstValue(customAttrIdx, intType), + GetConstValue(returnCustomAttrIdx, intType), }; auto methodData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(reflectMethodDataType->ToTypeInstance(), BfIRPopulateType_Full), methodDataVals); methodTypes.push_back(methodData); @@ -11369,14 +11381,13 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri { Fail(StrFormat("'%s' is not a valid attribute location for this declaration. Valid attribute locations for this declaration are '%s'. All attributes in this block will be ignored.", GetAttributesTargetListString(targetOverride).c_str(), GetAttributesTargetListString(attrTarget).c_str()), attributesDirective->mAttributeTargetSpecifier); // CS0657 - } - - success = false; + success = false; + } } if ((success) && (targetOverride != (BfAttributeTargets)0)) { - if ((targetOverride == BfAttributeTargets_ReturnValue) && (attrTarget == BfAttributeTargets_Method)) + if ((mCurMethodInstance != NULL) && (targetOverride == BfAttributeTargets_ReturnValue) && (attrTarget == BfAttributeTargets_Method)) { auto methodInfoEx = mCurMethodInstance->GetMethodInfoEx(); @@ -11389,11 +11400,9 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri methodInfoEx->mMethodCustomAttributes->mReturnCustomAttributes->mAttributes.push_back(customAttribute); } } - else - { - // Failed - ignore - success = false; - } + + // Mark as failed since we don't actually want to add this to the custom attributes set + success = false; } if (success)