mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +02:00
Fixed bugs with type extensions
This commit is contained in:
parent
55f3bdfa54
commit
38a650fc2e
5 changed files with 81 additions and 15 deletions
|
@ -549,6 +549,13 @@ void BfAutoComplete::AddCurrentTypes(BfTypeInstance* typeInst, const StringImpl&
|
|||
auto typeDef = typeInst->mTypeDef;
|
||||
for (auto nestedTypeDef : typeDef->mNestedTypes)
|
||||
{
|
||||
if (nestedTypeDef->mIsPartial)
|
||||
{
|
||||
nestedTypeDef = mSystem->GetCombinedPartial(nestedTypeDef);
|
||||
if (nestedTypeDef == NULL)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (CheckProtection(nestedTypeDef->mProtection, allowProtected, allowPrivate))
|
||||
AddTypeDef(nestedTypeDef, filter, onlyAttribute);
|
||||
}
|
||||
|
|
|
@ -745,6 +745,18 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
|
|||
int prevArgIdx = argIdx + prevImplicitParamCount;
|
||||
_CompareParamTypes(newMethodInstance->GetParamType(newArgIdx), prevMethodInstance->GetParamType(prevArgIdx));
|
||||
}
|
||||
|
||||
// Do generic constraint subset test directly to handle cases like "NotDisposed<T>()" vs "NOtDisposed<T>() where T : IDisposable"
|
||||
if ((newMethodInstance->GetNumGenericArguments() > 0) && (newMethodInstance->GetNumGenericArguments() == prevMethodInstance->GetNumGenericArguments()))
|
||||
{
|
||||
for (int genericParamIdx = 0; genericParamIdx < (int)newMethodInstance->GetNumGenericArguments(); genericParamIdx++)
|
||||
{
|
||||
auto newMethodGenericParam = newMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx];
|
||||
auto prevMethodGenericParam = prevMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx];
|
||||
SET_BETTER_OR_WORSE(mModule->AreConstraintsSubset(prevMethodGenericParam, newMethodGenericParam), mModule->AreConstraintsSubset(newMethodGenericParam, prevMethodGenericParam));
|
||||
}
|
||||
}
|
||||
|
||||
if ((isBetter) || (isWorse))
|
||||
{
|
||||
RETURN_RESULTS;
|
||||
|
@ -782,7 +794,37 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
|
|||
}
|
||||
}
|
||||
|
||||
RETURN_BETTER_OR_WORSE(newMethodDef->mCheckedKind == mCheckedKind, prevMethodDef->mCheckedKind == mCheckedKind);
|
||||
// If we have conditional type extensions that both define an implementation for a method, use the most-specific conditional extension constraints
|
||||
auto owner = newMethodInstance->GetOwner();
|
||||
if ((newMethodDef->mDeclaringType != prevMethodDef->mDeclaringType) && (owner->IsGenericTypeInstance()))
|
||||
{
|
||||
auto genericOwner = (BfGenericTypeInstance*)owner;
|
||||
if (genericOwner->mGenericExtensionInfo != NULL)
|
||||
{
|
||||
BfGenericExtensionEntry* newGenericExtesionEntry = NULL;
|
||||
BfGenericExtensionEntry* prevGenericExtesionEntry = NULL;
|
||||
if ((genericOwner->mGenericExtensionInfo->mExtensionMap.TryGetValue(newMethodDef->mDeclaringType, &newGenericExtesionEntry)) &&
|
||||
(genericOwner->mGenericExtensionInfo->mExtensionMap.TryGetValue(prevMethodDef->mDeclaringType, &prevGenericExtesionEntry)))
|
||||
{
|
||||
if ((newGenericExtesionEntry->mGenericParams.size() == prevGenericExtesionEntry->mGenericParams.size()))
|
||||
{
|
||||
for (int genericParamIdx = 0; genericParamIdx < (int)newGenericExtesionEntry->mGenericParams.size(); genericParamIdx++)
|
||||
{
|
||||
auto newMethodGenericParam = newGenericExtesionEntry->mGenericParams[genericParamIdx];
|
||||
auto prevMethodGenericParam = prevGenericExtesionEntry->mGenericParams[genericParamIdx];
|
||||
SET_BETTER_OR_WORSE(mModule->AreConstraintsSubset(prevMethodGenericParam, newMethodGenericParam), mModule->AreConstraintsSubset(newMethodGenericParam, prevMethodGenericParam));
|
||||
}
|
||||
}
|
||||
|
||||
if ((isBetter) || (isWorse))
|
||||
{
|
||||
RETURN_RESULTS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_BETTER_OR_WORSE(newMethodDef->mCheckedKind == mCheckedKind, prevMethodDef->mCheckedKind == mCheckedKind);
|
||||
|
||||
RETURN_RESULTS;
|
||||
}
|
||||
|
|
|
@ -1502,6 +1502,10 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
|
||||
for (auto baseTypeRef : typeDef->mBaseTypes)
|
||||
{
|
||||
SetAndRestoreValue<BfTypeReference*> prevTypeRef(mContext->mCurTypeState->mCurBaseTypeRef, baseTypeRef);
|
||||
SetAndRestoreValue<bool> prevIgnoreError(mIgnoreErrors, true);
|
||||
SetAndRestoreValue<bool> prevSkipTypeProtectionChecks(typeInstance->mSkipTypeProtectionChecks, true);
|
||||
|
||||
auto baseType = ResolveTypeRef(baseTypeRef, BfPopulateType_Declaration);
|
||||
if (baseType != NULL)
|
||||
{
|
||||
|
@ -3811,6 +3815,10 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
|||
if (ifaceMethodInst == NULL)
|
||||
continue;
|
||||
|
||||
// Don't even try to match generics
|
||||
if (!ifaceMethodInst->mMethodDef->mGenericParams.IsEmpty())
|
||||
continue;
|
||||
|
||||
auto iReturnType = ifaceMethodInst->mReturnType;
|
||||
if (iReturnType->IsSelf())
|
||||
iReturnType = typeInstance;
|
||||
|
@ -3931,7 +3939,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
|||
}
|
||||
}
|
||||
|
||||
if ((bestMethodInst->mMethodDef->HasBody()) && (matchedMethod == NULL))
|
||||
if ((bestMethodInst->mMethodDef->HasBody()) && (bestMethodInst->mMethodDef->mGenericParams.size() == 0) && (matchedMethod == NULL))
|
||||
{
|
||||
auto methodDef = bestMethodInst->mMethodDef;
|
||||
BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_ForeignMethodDef;
|
||||
|
@ -3939,10 +3947,10 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
|||
flags = (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_UnspecializedPass);
|
||||
auto methodInst = GetMethodInstance(typeInstance, methodDef, BfTypeVector(), flags, ifaceInst);
|
||||
if (methodInst)
|
||||
{
|
||||
{
|
||||
*matchedMethodRef = methodInst.mMethodInstance;
|
||||
|
||||
BfMethodInstance* newMethodInstance = *matchedMethodRef;
|
||||
BfMethodInstance* newMethodInstance = methodInst.mMethodInstance;
|
||||
BF_ASSERT(newMethodInstance->mIsForeignMethodDef);
|
||||
if (newMethodInstance->mMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingReference)
|
||||
mOnDemandMethodCount++;
|
||||
|
@ -4053,7 +4061,7 @@ void BfModule::AddMethodToWorkList(BfMethodInstance* methodInstance)
|
|||
return;
|
||||
|
||||
BF_ASSERT(mCompiler->mCompileState != BfCompiler::CompileState_VData);
|
||||
if (methodInstance->mIsReified)
|
||||
if ((methodInstance->mIsReified) && (!methodInstance->mIsUnspecialized))
|
||||
{
|
||||
BF_ASSERT(mCompiler->mCompileState != BfCompiler::CompileState_Unreified);
|
||||
}
|
||||
|
|
|
@ -2925,21 +2925,28 @@ void BfSystem::FinishCompositePartial(BfTypeDef* compositeTypeDef)
|
|||
VerifyTypeDef(nextRevision);
|
||||
}
|
||||
|
||||
BfTypeDef* BfSystem::GetCombinedPartial(BfTypeDef* typeDef)
|
||||
{
|
||||
if ((!typeDef->mIsPartial) || (typeDef->mIsCombinedPartial))
|
||||
return typeDef;
|
||||
|
||||
auto itr = mTypeDefs.TryGet(typeDef->mFullName);
|
||||
do
|
||||
{
|
||||
BF_ASSERT(typeDef->mIsPartial);
|
||||
typeDef = *itr;
|
||||
itr.MoveToNextHashMatch();
|
||||
} while (!typeDef->mIsCombinedPartial);
|
||||
return typeDef;
|
||||
}
|
||||
|
||||
BfTypeDef* BfSystem::GetOuterTypeNonPartial(BfTypeDef* typeDef)
|
||||
{
|
||||
auto checkType = typeDef->mOuterType;
|
||||
if ((checkType == NULL) || (!checkType->mIsPartial))
|
||||
return checkType;
|
||||
|
||||
auto itr = mTypeDefs.TryGet(checkType->mFullName);
|
||||
do
|
||||
{
|
||||
BF_ASSERT(checkType->mIsPartial);
|
||||
checkType = *itr;
|
||||
itr.MoveToNextHashMatch();
|
||||
}
|
||||
while (!checkType->mIsCombinedPartial);
|
||||
return checkType;
|
||||
return GetCombinedPartial(checkType);
|
||||
}
|
||||
|
||||
int BfSystem::GetGenericParamIdx(const Array<BfGenericParamDef*>& genericParams, const StringImpl& name)
|
||||
|
|
|
@ -1300,8 +1300,10 @@ public:
|
|||
bool ContainsNamespace(const BfAtomComposite& namespaceStr, BfProject* bfProject);
|
||||
void InjectNewRevision(BfTypeDef* typeDef);
|
||||
void AddToCompositePartial(BfPassInstance* passInstance, BfTypeDef* compositeTypeDef, BfTypeDef* partialTypeDef);
|
||||
void FinishCompositePartial(BfTypeDef* compositeTypeDef);
|
||||
void FinishCompositePartial(BfTypeDef* compositeTypeDef);
|
||||
BfTypeDef* GetCombinedPartial(BfTypeDef* typeDef);
|
||||
BfTypeDef* GetOuterTypeNonPartial(BfTypeDef* typeDef);
|
||||
|
||||
|
||||
int GetGenericParamIdx(const Array<BfGenericParamDef*>& genericParams, const StringImpl& name);
|
||||
int GetGenericParamIdx(const Array<BfGenericParamDef*>& genericParams, BfTypeReference* typeRef);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue