diff --git a/IDEHelper/Compiler/BfContext.h b/IDEHelper/Compiler/BfContext.h index 6efd1fdd..c9ab4227 100644 --- a/IDEHelper/Compiler/BfContext.h +++ b/IDEHelper/Compiler/BfContext.h @@ -143,10 +143,11 @@ public: BfPopulateType mPopulateType; BfTypeReference* mCurBaseTypeRef; + BfTypeInstance* mCurBaseType; BfTypeReference* mCurAttributeTypeRef; BfFieldDef* mCurFieldDef; BfTypeDef* mCurTypeDef; - BfTypeDef* mForceActiveTypeDef; + BfTypeDef* mForceActiveTypeDef; ResolveKind mResolveKind; BfAstNode* mCurVarInitializer; int mArrayInitializerSize; @@ -160,6 +161,7 @@ public: mPopulateType = BfPopulateType_Identity; mCurBaseTypeRef = NULL; + mCurBaseType = NULL; mCurFieldDef = NULL; mCurAttributeTypeRef = NULL; mCurTypeDef = NULL; diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 44a593d5..9f2df9a8 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -3022,7 +3022,10 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy bool populateBase = !typeInstance->mTypeFailed; auto checkType = ResolveTypeRef(checkTypeRef, BfPopulateType_Declaration); if ((checkType != NULL) && (!checkType->IsInterface()) && (populateBase)) + { + SetAndRestoreValue prevBaseType(mContext->mCurTypeState->mCurBaseType, checkType->ToTypeInstance()); PopulateType(checkType, BfPopulateType_Data); + } if (typeInstance->mDefineState >= BfTypeDefineState_Defined) { @@ -12793,6 +12796,19 @@ bool BfModule::TypeIsSubTypeOf(BfTypeInstance* srcType, BfTypeInstance* wantType if (srcType->mDefineState < BfTypeDefineState_HasInterfaces) { + if (srcType->mDefineState == BfTypeDefineState_ResolvingBaseType) + { + auto typeState = mContext->mCurTypeState; + while (typeState != NULL) + { + if ((typeState->mTypeInstance == srcType) && (typeState->mCurBaseType != NULL)) + { + return TypeIsSubTypeOf(typeState->mCurBaseType, wantType, checkAccessibility); + } + 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 diff --git a/IDEHelper/Tests/src/Classes.bf b/IDEHelper/Tests/src/Classes.bf new file mode 100644 index 00000000..b4d4c0f0 --- /dev/null +++ b/IDEHelper/Tests/src/Classes.bf @@ -0,0 +1,26 @@ +namespace Tests +{ + class Classes + { + public abstract class Plugin where T : Plugin, new, class + { + public abstract void OnLoad(); + public abstract void OnUnload(); + } + + public abstract class ProgramPlugin : Plugin where T : ProgramPlugin + { + } + + public class ExamplePlugin : ProgramPlugin + { + public override void OnLoad() + { + } + + public override void OnUnload() + { + } + } + } +}