From b3647601052f8bd64674f373ed47df698e5c6106 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Thu, 3 Mar 2022 12:55:56 -0800 Subject: [PATCH] Fixed reflection of generic attributes --- IDEHelper/Compiler/BfModule.h | 1 + IDEHelper/Compiler/BfModuleTypeUtils.cpp | 68 ++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index 182c286b..e33a097e 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -1890,6 +1890,7 @@ public: bool TypeHasParentOrEquals(BfTypeDef* checkChildTypeDef, BfTypeDef* checkParentTypeDef); BfTypeDef* FindCommonOuterType(BfTypeDef* type, BfTypeDef* type2); bool TypeIsSubTypeOf(BfTypeInstance* srcType, BfTypeInstance* wantType, bool checkAccessibility = true); + bool TypeIsSubTypeOf(BfTypeInstance* srcType, BfTypeDef* wantType); int GetTypeDistance(BfType* fromType, BfType* toType); bool IsTypeMoreSpecific(BfType* leftType, BfType* rightType); bool GetBasePropertyDef(BfPropertyDef*& propDef, BfTypeInstance*& typeInst); diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 0d1003db..84f0355b 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -5564,6 +5564,9 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) } } + if (TypeIsSubTypeOf(typeInstance, mCompiler->mAttributeTypeDef)) + wantsOnDemandMethods = false; + //bool allDeclsRequired = (mIsReified) && (mCompiler->mOptions.mEmitDebugInfo) && (); bool allDeclsRequired = false; //if ((mIsReified) && (mCompiler->mOptions.mEmitDebugInfo) && (!mCompiler->mWantsDeferMethodDecls)) @@ -13979,6 +13982,71 @@ bool BfModule::TypeIsSubTypeOf(BfTypeInstance* srcType, BfTypeInstance* wantType return TypeIsSubTypeOf(srcBaseType, wantType); } +bool BfModule::TypeIsSubTypeOf(BfTypeInstance* srcType, BfTypeDef* wantType) +{ + if ((srcType == NULL) || (wantType == NULL)) + return false; + if (srcType->IsInstanceOf(wantType)) + return true; + + if (srcType->mDefineState < BfTypeDefineState_HasInterfaces) + { + if (srcType->mDefineState == BfTypeDefineState_ResolvingBaseType) + { + auto typeState = mContext->mCurTypeState; + while (typeState != NULL) + { + if ((typeState->mType == srcType) && (typeState->mCurBaseType != NULL)) + { + return TypeIsSubTypeOf(typeState->mCurBaseType, wantType); + } + typeState = typeState->mPrevState; + } + } + + // Type is incomplete. We don't do the IsIncomplete check here because of re-entry + // While handling 'var' resolution, we don't want to force a PopulateType reentry + // but we do have enough information for TypeIsSubTypeOf + PopulateType(srcType, BfPopulateType_Interfaces); + } + + if (wantType->mTypeCode == BfTypeCode_Interface) + { + BfTypeDef* checkActiveTypeDef = NULL; + + auto checkType = srcType; + while (checkType != NULL) + { + for (auto ifaceInst : checkType->mInterfaces) + { + if (ifaceInst.mInterfaceType->IsInstanceOf(wantType)) + return true; + } + checkType = checkType->GetImplBaseType(); + if ((checkType != NULL) && (checkType->mDefineState < BfTypeDefineState_HasInterfaces)) + { + PopulateType(checkType, BfPopulateType_Interfaces); + } + } + + if (srcType->IsTypedPrimitive()) + { + BfType* underlyingType = srcType->GetUnderlyingType(); + if (underlyingType->IsWrappableType()) + { + BfTypeInstance* wrappedType = GetWrappedStructType(underlyingType); + if ((wrappedType != NULL) && (wrappedType != srcType)) + return TypeIsSubTypeOf(wrappedType, wantType); + } + } + + return false; + } + + auto srcBaseType = srcType->mBaseType; + return TypeIsSubTypeOf(srcBaseType, wantType); +} + // Positive value means that toType encompasses fromType, negative value means toType is encompassed by formType // INT_MAX means the types are not related int BfModule::GetTypeDistance(BfType* fromType, BfType* toType)