1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-09 03:52:19 +02:00

Better fix for VerifyTypeLookups

This commit is contained in:
Brian Fiete 2021-02-28 11:41:00 -08:00
parent a412452bac
commit c598944f52
4 changed files with 87 additions and 45 deletions

View file

@ -2276,8 +2276,18 @@ void BfContext::VerifyTypeLookups(BfTypeInstance* typeInst)
// so the mNextRevision will be ignored // so the mNextRevision will be ignored
auto useTypeDef = lookupEntry.mUseTypeDef; auto useTypeDef = lookupEntry.mUseTypeDef;
BfTypeDef* ambiguousTypeDef = NULL; BfTypeDef* ambiguousTypeDef = NULL;
BfTypeDef* result = typeInst->mModule->FindTypeDefRaw(lookupEntry.mName, lookupEntry.mNumGenericParams, typeInst, useTypeDef, NULL); BfTypeLookupResult* lookupResult = &lookupEntryPair.mValue;
if (result != lookupEntryPair.mValue.mTypeDef)
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; isDirty = true;
} }

View file

@ -1823,7 +1823,7 @@ public:
void ShowAmbiguousTypeError(BfAstNode* refNode, BfTypeDef* typeDef, BfTypeDef* otherTypeDef); void ShowAmbiguousTypeError(BfAstNode* refNode, BfTypeDef* typeDef, BfTypeDef* otherTypeDef);
void ShowGenericArgCountError(BfAstNode* typeRef, int wantedGenericParams); 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* 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 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(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); BfTypeDef* FindTypeDef(BfTypeReference* typeRef, BfTypeInstance* typeInstanceOverride = NULL, BfTypeLookupError* error = NULL, int numGenericParams = 0, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0);

View file

@ -8382,7 +8382,7 @@ BfTypeDef* BfModule::GetActiveTypeDef(BfTypeInstance* typeInstanceOverride, bool
return useTypeDef; 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)) if ((findName.mSize == 1) && (findName.mParts[0]->mIsSystemType))
{ {
@ -8408,56 +8408,68 @@ BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGene
BfTypeDef* protErrorTypeDef = NULL; BfTypeDef* protErrorTypeDef = NULL;
BfTypeInstance* protErrorOuterType = NULL; BfTypeInstance* protErrorOuterType = NULL;
if ((!lookupCtx.HasValidMatch()) && (typeInstance != NULL)) BfTypeDef* foundInnerType = NULL;
{
std::function<bool(BfTypeInstance*)> _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;
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<bool(BfTypeInstance*)> _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; foundInnerType = lookupCtx.mBestTypeDef;
protErrorOuterType = checkTypeInst;
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); checkTypeInst = typeInstance;
allowPrivate = false; allowPrivate = true;
} while (checkTypeInst != NULL)
checkTypeInst = typeInstance;
allowPrivate = true;
while (checkTypeInst != NULL)
{
auto outerTypeInst = GetOuterType(checkTypeInst);
if (outerTypeInst != NULL)
{ {
if (_CheckType(outerTypeInst)) auto outerTypeInst = GetOuterType(checkTypeInst);
return true; 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()) 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)) 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 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; return lookupCtx.mBestTypeDef;
} }
@ -8569,7 +8584,10 @@ BfTypeDef* BfModule::FindTypeDef(const BfAtomComposite& findName, int numGeneric
BfTypeLookupError localError; BfTypeLookupError localError;
BfTypeLookupError* errorPtr = (error != NULL) ? error : &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()) if (prevAllocSize != typeInstance->mLookupResults.size())
{ {

View file

@ -1668,11 +1668,25 @@ struct BfTypeLookupResult
{ {
BfTypeDef* mTypeDef; BfTypeDef* mTypeDef;
bool mForceLookup; bool mForceLookup;
bool mFoundInnerType;
BfTypeLookupResult() BfTypeLookupResult()
{ {
mTypeDef = NULL; mTypeDef = NULL;
mForceLookup = false; mForceLookup = false;
mFoundInnerType = false;
}
};
struct BfTypeLookupResultCtx
{
BfTypeLookupResult* mResult;
bool mIsVerify;
BfTypeLookupResultCtx()
{
mResult = NULL;
mIsVerify = false;
} }
}; };