mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 20:42:21 +02:00
Fixed type lookup for comptime emitted type refs in specialized generics
This commit is contained in:
parent
d34976864c
commit
723010fd9d
4 changed files with 103 additions and 28 deletions
|
@ -10025,6 +10025,8 @@ BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGene
|
|||
skipCheckBaseType = mContext->mCurTypeState->mType->ToTypeInstance();
|
||||
}
|
||||
|
||||
BfProject* useProject = useTypeDef->mProject;
|
||||
|
||||
BfTypeDefLookupContext lookupCtx;
|
||||
bool allowPrivate = true;
|
||||
|
||||
|
@ -10036,6 +10038,13 @@ BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGene
|
|||
|
||||
BfTypeDef* foundInnerType = NULL;
|
||||
|
||||
if ((resolveFlags & BfResolveTypeRefFlag_SpecializedProject) != 0)
|
||||
{
|
||||
if (typeInstance->mGenericTypeInfo->mProjectsReferenced.empty())
|
||||
typeInstance->GenerateProjectsReferenced();
|
||||
lookupCtx.mCheckProjects = &typeInstance->mGenericTypeInfo->mProjectsReferenced;
|
||||
}
|
||||
|
||||
if ((lookupResultCtx != NULL) && (lookupResultCtx->mIsVerify))
|
||||
{
|
||||
if (lookupResultCtx->mResult->mFoundInnerType)
|
||||
|
@ -10053,7 +10062,7 @@ BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGene
|
|||
{
|
||||
if (!checkTypeInst->mTypeDef->mNestedTypes.IsEmpty())
|
||||
{
|
||||
if (mSystem->FindTypeDef(findName, numGenericArgs, useTypeDef->mProject, checkTypeInst->mTypeDef->mFullNameEx, allowPrivate, &lookupCtx))
|
||||
if (mSystem->FindTypeDef(findName, numGenericArgs, useProject, checkTypeInst->mTypeDef->mFullNameEx, allowPrivate, &lookupCtx))
|
||||
{
|
||||
foundInnerType = lookupCtx.mBestTypeDef;
|
||||
|
||||
|
@ -10101,14 +10110,14 @@ BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGene
|
|||
if (!lookupCtx.HasValidMatch())
|
||||
{
|
||||
if (mSystem->mTypeDefs.TryGet(findName, NULL))
|
||||
mSystem->FindTypeDef(findName, numGenericArgs, useTypeDef->mProject, BfAtomComposite(), allowPrivate, &lookupCtx);
|
||||
mSystem->FindTypeDef(findName, numGenericArgs, useProject, BfAtomComposite(), allowPrivate, &lookupCtx);
|
||||
|
||||
for (auto& checkNamespace : useTypeDef->mNamespaceSearch)
|
||||
{
|
||||
BfAtom* atom = findName.mParts[0];
|
||||
BfAtom* prevAtom = checkNamespace.mParts[checkNamespace.mSize - 1];
|
||||
if (atom->mPrevNamesMap.ContainsKey(prevAtom))
|
||||
mSystem->FindTypeDef(findName, numGenericArgs, useTypeDef->mProject, checkNamespace, allowPrivate, &lookupCtx);
|
||||
mSystem->FindTypeDef(findName, numGenericArgs, useProject, checkNamespace, allowPrivate, &lookupCtx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10119,7 +10128,7 @@ BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGene
|
|||
{
|
||||
for (auto staticTypeInstance : staticSearch->mStaticTypes)
|
||||
{
|
||||
if (mSystem->FindTypeDef(findName, numGenericArgs, useTypeDef->mProject, staticTypeInstance->mTypeDef->mFullNameEx, false, &lookupCtx))
|
||||
if (mSystem->FindTypeDef(findName, numGenericArgs, useProject, staticTypeInstance->mTypeDef->mFullNameEx, false, &lookupCtx))
|
||||
{
|
||||
if (lookupCtx.HasValidMatch())
|
||||
break;
|
||||
|
@ -10232,6 +10241,7 @@ BfTypeDef* BfModule::FindTypeDef(const BfAtomComposite& findName, int numGeneric
|
|||
BfTypeLookupEntry typeLookupEntry;
|
||||
typeLookupEntry.mName.Reference(findName);
|
||||
typeLookupEntry.mNumGenericParams = numGenericArgs;
|
||||
typeLookupEntry.mFlags = ((resolveFlags & BfResolveTypeRefFlag_SpecializedProject) != 0) ? BfTypeLookupEntry::Flags_SpecializedProject : BfTypeLookupEntry::Flags_None;
|
||||
typeLookupEntry.mUseTypeDef = useTypeDef;
|
||||
|
||||
BfTypeLookupEntry* typeLookupEntryPtr = NULL;
|
||||
|
@ -10799,10 +10809,27 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
|||
}
|
||||
|
||||
BfTypeDef* curTypeDef = NULL;
|
||||
Array<BfProject*>* checkProjects = NULL;
|
||||
|
||||
if (contextTypeInstance != NULL)
|
||||
{
|
||||
curTypeDef = contextTypeInstance->mTypeDef;
|
||||
|
||||
if ((curTypeDef->IsEmitted()) && (!typeRef->IsTemporary()))
|
||||
{
|
||||
auto parser = typeRef->GetParser();
|
||||
if ((parser != NULL) && (parser->mIsEmitted))
|
||||
{
|
||||
if (contextTypeInstance->IsGenericTypeInstance())
|
||||
{
|
||||
resolveFlags = (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_SpecializedProject);
|
||||
if (contextTypeInstance->mGenericTypeInfo->mProjectsReferenced.empty())
|
||||
contextTypeInstance->GenerateProjectsReferenced();
|
||||
checkProjects = &contextTypeInstance->mGenericTypeInfo->mProjectsReferenced;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check generics first
|
||||
auto namedTypeRef = BfNodeDynCastExact<BfNamedTypeReference>(typeRef);
|
||||
auto directStrTypeRef = BfNodeDynCastExact<BfDirectStrTypeReference>(typeRef);
|
||||
|
@ -11166,7 +11193,24 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
|||
if (activeTypeDef != NULL)
|
||||
bfProject = activeTypeDef->mProject;
|
||||
|
||||
bool leftIsNamespace = false;
|
||||
if (mSystem->ContainsNamespace(leftComposite, bfProject))
|
||||
{
|
||||
leftIsNamespace = true;
|
||||
}
|
||||
else if (checkProjects != NULL)
|
||||
{
|
||||
for (auto checkProject : *checkProjects)
|
||||
{
|
||||
if (mSystem->ContainsNamespace(leftComposite, checkProject))
|
||||
{
|
||||
leftIsNamespace = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (leftIsNamespace)
|
||||
{
|
||||
qualifiedTypeRef->mLeft->ToString(findName);
|
||||
findName.Append('.');
|
||||
|
@ -11496,7 +11540,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
|||
(BfResolveTypeRefFlag_NoCreate | BfResolveTypeRefFlag_IgnoreLookupError | BfResolveTypeRefFlag_DisallowComptime |
|
||||
BfResolveTypeRefFlag_AllowInferredSizedArray | BfResolveTypeRefFlag_Attribute | BfResolveTypeRefFlag_AllowUnboundGeneric |
|
||||
BfResolveTypeRefFlag_ForceUnboundGeneric | BfResolveTypeRefFlag_AllowGenericParamConstValue |
|
||||
BfResolveTypeRefFlag_AllowImplicitConstExpr));
|
||||
BfResolveTypeRefFlag_AllowImplicitConstExpr | BfResolveTypeRefFlag_SpecializedProject));
|
||||
lookupCtx.mRootTypeRef = typeRef;
|
||||
lookupCtx.mRootTypeDef = typeDef;
|
||||
lookupCtx.mModule = this;
|
||||
|
|
|
@ -41,7 +41,8 @@ enum BfResolveTypeRefFlags
|
|||
BfResolveTypeRefFlag_AllowImplicitConstExpr = 0x20000,
|
||||
BfResolveTypeRefFlag_AllowUnboundGeneric = 0x40000,
|
||||
BfResolveTypeRefFlag_ForceUnboundGeneric = 0x80000,
|
||||
BfResolveTypeRefFlag_IgnoreProtection = 0x100000
|
||||
BfResolveTypeRefFlag_IgnoreProtection = 0x100000,
|
||||
BfResolveTypeRefFlag_SpecializedProject = 0x200000
|
||||
};
|
||||
|
||||
enum BfTypeNameFlags : uint16
|
||||
|
@ -1721,8 +1722,15 @@ public:
|
|||
|
||||
struct BfTypeLookupEntry
|
||||
{
|
||||
enum Flags : uint8
|
||||
{
|
||||
Flags_None,
|
||||
Flags_SpecializedProject
|
||||
};
|
||||
|
||||
BfAtomComposite mName;
|
||||
int mNumGenericParams;
|
||||
int16 mNumGenericParams;
|
||||
Flags mFlags;
|
||||
uint32 mAtomUpdateIdx;
|
||||
BfTypeDef* mUseTypeDef;
|
||||
|
||||
|
@ -1730,6 +1738,7 @@ struct BfTypeLookupEntry
|
|||
{
|
||||
return (mName == rhs.mName) &&
|
||||
(mNumGenericParams == rhs.mNumGenericParams) &&
|
||||
(mFlags == rhs.mFlags) &&
|
||||
(mUseTypeDef == rhs.mUseTypeDef);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -2663,34 +2663,54 @@ bool BfSystem::FindTypeDef(const BfAtomComposite& findName, int numGenericArgs,
|
|||
continue;
|
||||
}
|
||||
|
||||
if ((typeDef->mFullName == *qualifiedFindNamePtr) && (CheckTypeDefReference(typeDef, project)))
|
||||
if (typeDef->mFullName == *qualifiedFindNamePtr)
|
||||
{
|
||||
int curPri = 0;
|
||||
if (typeDef->mProtection < minProtection)
|
||||
curPri -= 1;
|
||||
if (typeDef->IsGlobalsContainer())
|
||||
curPri -= 2;
|
||||
if (typeDef->mGenericParamDefs.size() != numGenericArgs)
|
||||
bool isProjectValid = false;
|
||||
if (CheckTypeDefReference(typeDef, project))
|
||||
{
|
||||
// Still allow SOME match even if we put in the wrong number of generic args
|
||||
curPri -= 4;
|
||||
isProjectValid = true;
|
||||
}
|
||||
if ((typeDef->mPartials.mSize > 0) && (typeDef->mPartials[0]->IsExtension()))
|
||||
else if ((ctx != NULL) && (ctx->mCheckProjects != NULL))
|
||||
{
|
||||
// Is a failed extension
|
||||
curPri -= 8;
|
||||
for (auto checkProject : *ctx->mCheckProjects)
|
||||
{
|
||||
if (CheckTypeDefReference(typeDef, checkProject))
|
||||
{
|
||||
isProjectValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((curPri > ctx->mBestPri) || (ctx->mBestTypeDef == NULL))
|
||||
if (isProjectValid)
|
||||
{
|
||||
ctx->mBestTypeDef = typeDef;
|
||||
ctx->mAmbiguousTypeDef = NULL;
|
||||
ctx->mBestPri = curPri;
|
||||
hadMatch = true;
|
||||
}
|
||||
else if (curPri == ctx->mBestPri)
|
||||
{
|
||||
ctx->mAmbiguousTypeDef = typeDef;
|
||||
int curPri = 0;
|
||||
if (typeDef->mProtection < minProtection)
|
||||
curPri -= 1;
|
||||
if (typeDef->IsGlobalsContainer())
|
||||
curPri -= 2;
|
||||
if (typeDef->mGenericParamDefs.size() != numGenericArgs)
|
||||
{
|
||||
// Still allow SOME match even if we put in the wrong number of generic args
|
||||
curPri -= 4;
|
||||
}
|
||||
if ((typeDef->mPartials.mSize > 0) && (typeDef->mPartials[0]->IsExtension()))
|
||||
{
|
||||
// Is a failed extension
|
||||
curPri -= 8;
|
||||
}
|
||||
|
||||
if ((curPri > ctx->mBestPri) || (ctx->mBestTypeDef == NULL))
|
||||
{
|
||||
ctx->mBestTypeDef = typeDef;
|
||||
ctx->mAmbiguousTypeDef = NULL;
|
||||
ctx->mBestPri = curPri;
|
||||
hadMatch = true;
|
||||
}
|
||||
else if (curPri == ctx->mBestPri)
|
||||
{
|
||||
ctx->mAmbiguousTypeDef = typeDef;
|
||||
}
|
||||
}
|
||||
}
|
||||
itr.MoveToNextHashMatch();
|
||||
|
|
|
@ -1001,6 +1001,7 @@ public:
|
|||
int mBestPri;
|
||||
BfTypeDef* mBestTypeDef;
|
||||
BfTypeDef* mAmbiguousTypeDef;
|
||||
Array<BfProject*>* mCheckProjects;
|
||||
|
||||
public:
|
||||
BfTypeDefLookupContext()
|
||||
|
@ -1008,6 +1009,7 @@ public:
|
|||
mBestPri = (int)0x80000000;
|
||||
mBestTypeDef = NULL;
|
||||
mAmbiguousTypeDef = NULL;
|
||||
mCheckProjects = NULL;
|
||||
}
|
||||
|
||||
bool HasValidMatch()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue