diff --git a/IDEHelper/Compiler/BfContext.cpp b/IDEHelper/Compiler/BfContext.cpp index e461e941..412c29e1 100644 --- a/IDEHelper/Compiler/BfContext.cpp +++ b/IDEHelper/Compiler/BfContext.cpp @@ -2276,8 +2276,18 @@ void BfContext::VerifyTypeLookups(BfTypeInstance* typeInst) // so the mNextRevision will be ignored auto useTypeDef = lookupEntry.mUseTypeDef; BfTypeDef* ambiguousTypeDef = NULL; - BfTypeDef* result = typeInst->mModule->FindTypeDefRaw(lookupEntry.mName, lookupEntry.mNumGenericParams, typeInst, useTypeDef, NULL); - if (result != lookupEntryPair.mValue.mTypeDef) + BfTypeLookupResult* lookupResult = &lookupEntryPair.mValue; + + BfTypeLookupResultCtx lookupResultCtx; + lookupResultCtx.mResult = lookupResult; + lookupResultCtx.mIsVerify = true; + + BfTypeDef* result = typeInst->mModule->FindTypeDefRaw(lookupEntry.mName, lookupEntry.mNumGenericParams, typeInst, useTypeDef, NULL, &lookupResultCtx); + if ((result == NULL) && (lookupResult->mFoundInnerType)) + { + // Allow this- if there were new types added then the types would be rebuilt already + } + else if (result != lookupResult->mTypeDef) { isDirty = true; } diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index ed3dcf89..08cebbd6 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -1823,7 +1823,7 @@ public: void ShowAmbiguousTypeError(BfAstNode* refNode, BfTypeDef* typeDef, BfTypeDef* otherTypeDef); void ShowGenericArgCountError(BfAstNode* typeRef, int wantedGenericParams); BfTypeDef* GetActiveTypeDef(BfTypeInstance* typeInstanceOverride = NULL, bool useMixinDecl = false); // useMixinDecl is useful for type lookup, but we don't want the decl project to limit what methods the user can call - BfTypeDef* FindTypeDefRaw(const BfAtomComposite& findName, int numGenericArgs, BfTypeInstance* typeInstance, BfTypeDef* useTypeDef, BfTypeLookupError* error); + BfTypeDef* FindTypeDefRaw(const BfAtomComposite& findName, int numGenericArgs, BfTypeInstance* typeInstance, BfTypeDef* useTypeDef, BfTypeLookupError* error, BfTypeLookupResultCtx* lookupResultCtx = NULL); BfTypeDef* FindTypeDef(const BfAtomComposite& findName, int numGenericArgs = 0, BfTypeInstance* typeInstanceOverride = NULL, BfTypeLookupError* error = NULL); BfTypeDef* FindTypeDef(const StringImpl& typeName, int numGenericArgs = 0, BfTypeInstance* typeInstanceOverride = NULL, BfTypeLookupError* error = NULL); BfTypeDef* FindTypeDef(BfTypeReference* typeRef, BfTypeInstance* typeInstanceOverride = NULL, BfTypeLookupError* error = NULL, int numGenericParams = 0, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0); diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index b66a96c3..f97f83a9 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -8382,7 +8382,7 @@ BfTypeDef* BfModule::GetActiveTypeDef(BfTypeInstance* typeInstanceOverride, bool return useTypeDef; } -BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGenericArgs, BfTypeInstance* typeInstance, BfTypeDef* useTypeDef, BfTypeLookupError* error) +BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGenericArgs, BfTypeInstance* typeInstance, BfTypeDef* useTypeDef, BfTypeLookupError* error, BfTypeLookupResultCtx* lookupResultCtx) { if ((findName.mSize == 1) && (findName.mParts[0]->mIsSystemType)) { @@ -8408,56 +8408,68 @@ BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGene BfTypeDef* protErrorTypeDef = NULL; BfTypeInstance* protErrorOuterType = NULL; - if ((!lookupCtx.HasValidMatch()) && (typeInstance != NULL)) - { - std::function _CheckType = [&](BfTypeInstance* typeInstance) - { - auto checkTypeInst = typeInstance; - allowPrivate = true; - while (checkTypeInst != NULL) - { - if (!checkTypeInst->mTypeDef->mNestedTypes.IsEmpty()) - { - if (mSystem->FindTypeDef(findName, numGenericArgs, useTypeDef->mProject, checkTypeInst->mTypeDef->mFullNameEx, allowPrivate, &lookupCtx)) - { - if (lookupCtx.HasValidMatch()) - return true; + BfTypeDef* foundInnerType = NULL; - if ((lookupCtx.mBestTypeDef->mProtection == BfProtection_Private) && (!allowPrivate)) + if ((lookupResultCtx != NULL) && (lookupResultCtx->mIsVerify)) + { + if (lookupResultCtx->mResult->mFoundInnerType) + return lookupCtx.mBestTypeDef; + } + else + { + if ((!lookupCtx.HasValidMatch()) && (typeInstance != NULL)) + { + std::function _CheckType = [&](BfTypeInstance* typeInstance) + { + auto checkTypeInst = typeInstance; + allowPrivate = true; + while (checkTypeInst != NULL) + { + if (!checkTypeInst->mTypeDef->mNestedTypes.IsEmpty()) + { + if (mSystem->FindTypeDef(findName, numGenericArgs, useTypeDef->mProject, checkTypeInst->mTypeDef->mFullNameEx, allowPrivate, &lookupCtx)) { - protErrorTypeDef = lookupCtx.mBestTypeDef; - protErrorOuterType = checkTypeInst; + foundInnerType = lookupCtx.mBestTypeDef; + + if (lookupCtx.HasValidMatch()) + return true; + + if ((lookupCtx.mBestTypeDef->mProtection == BfProtection_Private) && (!allowPrivate)) + { + protErrorTypeDef = lookupCtx.mBestTypeDef; + protErrorOuterType = checkTypeInst; + } } } + if (checkTypeInst == skipCheckBaseType) + break; + + checkTypeInst = GetBaseType(checkTypeInst); + allowPrivate = false; } - if (checkTypeInst == skipCheckBaseType) - break; - checkTypeInst = GetBaseType(checkTypeInst); - allowPrivate = false; - } - - checkTypeInst = typeInstance; - allowPrivate = true; - while (checkTypeInst != NULL) - { - auto outerTypeInst = GetOuterType(checkTypeInst); - if (outerTypeInst != NULL) + checkTypeInst = typeInstance; + allowPrivate = true; + while (checkTypeInst != NULL) { - if (_CheckType(outerTypeInst)) - return true; + auto outerTypeInst = GetOuterType(checkTypeInst); + if (outerTypeInst != NULL) + { + if (_CheckType(outerTypeInst)) + return true; + } + if (checkTypeInst == skipCheckBaseType) + break; + + checkTypeInst = GetBaseType(checkTypeInst); + allowPrivate = false; } - if (checkTypeInst == skipCheckBaseType) - break; - - checkTypeInst = GetBaseType(checkTypeInst); - allowPrivate = false; - } - return false; - }; + return false; + }; - _CheckType(typeInstance); + _CheckType(typeInstance); + } } if (!lookupCtx.HasValidMatch()) @@ -8515,6 +8527,9 @@ BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGene if ((protErrorTypeDef != NULL) && (lookupCtx.mBestTypeDef == protErrorTypeDef) && (error != NULL) && (error->mRefNode != NULL)) Fail(StrFormat("'%s.%s' is inaccessible due to its protection level", TypeToString(protErrorOuterType).c_str(), findName.ToString().c_str()), error->mRefNode); // CS0122 + if ((lookupResultCtx != NULL) && (lookupResultCtx->mResult != NULL) && (!lookupResultCtx->mIsVerify) && (foundInnerType != NULL) && (foundInnerType == lookupCtx.mBestTypeDef)) + lookupResultCtx->mResult->mFoundInnerType = true; + return lookupCtx.mBestTypeDef; } @@ -8569,7 +8584,10 @@ BfTypeDef* BfModule::FindTypeDef(const BfAtomComposite& findName, int numGeneric BfTypeLookupError localError; BfTypeLookupError* errorPtr = (error != NULL) ? error : &localError; - auto typeDef = FindTypeDefRaw(findName, numGenericArgs, typeInstance, useTypeDef, errorPtr); + + BfTypeLookupResultCtx lookupResultCtx; + lookupResultCtx.mResult = resultPtr; + auto typeDef = FindTypeDefRaw(findName, numGenericArgs, typeInstance, useTypeDef, errorPtr, &lookupResultCtx); if (prevAllocSize != typeInstance->mLookupResults.size()) { diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.h b/IDEHelper/Compiler/BfResolvedTypeUtils.h index e17c74a8..7a02ee55 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.h +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.h @@ -1668,11 +1668,25 @@ struct BfTypeLookupResult { BfTypeDef* mTypeDef; bool mForceLookup; + bool mFoundInnerType; BfTypeLookupResult() { mTypeDef = NULL; mForceLookup = false; + mFoundInnerType = false; + } +}; + +struct BfTypeLookupResultCtx +{ + BfTypeLookupResult* mResult; + bool mIsVerify; + + BfTypeLookupResultCtx() + { + mResult = NULL; + mIsVerify = false; } };