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

Allow overrides to specify unique default param values

This commit is contained in:
Brian Fiete 2020-02-20 17:18:53 -08:00
parent c2c2c24ac8
commit 40c404f329
3 changed files with 30 additions and 12 deletions

View file

@ -1144,7 +1144,7 @@ bool BfMethodMatcher::InferFromGenericConstraints(BfGenericParamInstance* generi
return true; return true;
} }
bool BfMethodMatcher::CheckMethod(BfTypeInstance* typeInstance, BfMethodDef* checkMethod, bool isFailurePass) bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInstance* typeInstance, BfMethodDef* checkMethod, bool isFailurePass)
{ {
BP_ZONE("BfMethodMatcher::CheckMethod"); BP_ZONE("BfMethodMatcher::CheckMethod");
@ -1172,6 +1172,19 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* typeInstance, BfMethodDef* che
return false; return false;
} }
if ((checkMethod->mIsVirtual) && (!checkMethod->mIsOverride) && (!mBypassVirtual) &&
(targetTypeInstance != NULL) && (targetTypeInstance->IsObject()))
{
mModule->PopulateType(targetTypeInstance, BfPopulateType_DataAndMethods);
BfVirtualMethodEntry& vEntry = targetTypeInstance->mVirtualMethodTable[methodInstance->mVirtualTableIdx];
auto implMethod = (BfMethodInstance*)vEntry.mImplementingMethod;
if (implMethod != methodInstance)
{
SetAndRestoreValue<bool> prevBypassVirtual(mBypassVirtual, true);
return CheckMethod(targetTypeInstance, implMethod->GetOwner(), implMethod->mMethodDef, isFailurePass);
}
}
HashSet<int> allowEmptyGenericSet; HashSet<int> allowEmptyGenericSet;
BfAutoComplete* autoComplete = NULL; BfAutoComplete* autoComplete = NULL;
if ((mModule->mCompiler->mResolvePassData != NULL) && (!isFailurePass)) if ((mModule->mCompiler->mResolvePassData != NULL) && (!isFailurePass))
@ -1703,6 +1716,10 @@ bool BfMethodMatcher::CheckType(BfTypeInstance* typeInstance, BfTypedValue targe
} }
} }
BfTypeInstance* targetTypeInstance = NULL;
if (target.mType != NULL)
targetTypeInstance = target.mType->ToTypeInstance();
while (true) while (true)
{ {
curTypeDef->PopulateMemberSets(); curTypeDef->PopulateMemberSets();
@ -1784,7 +1801,7 @@ bool BfMethodMatcher::CheckType(BfTypeInstance* typeInstance, BfTypedValue targe
} }
} }
CheckMethod(curTypeInst, checkMethod, isFailurePass); CheckMethod(targetTypeInstance, curTypeInst, checkMethod, isFailurePass);
if ((isFailurePass) && if ((isFailurePass) &&
((mBestMethodDef == checkMethod) || (mBackupMethodDef == checkMethod))) ((mBestMethodDef == checkMethod) || (mBackupMethodDef == checkMethod)))
mMatchFailKind = matchFailKind; mMatchFailKind = matchFailKind;
@ -2033,7 +2050,7 @@ void BfMethodMatcher::CheckOuterTypeStaticMethods(BfTypeInstance* typeInstance,
if ((!isFailurePass) && (!mModule->CheckProtection(checkMethod->mProtection, allowProtected, allowPrivate))) if ((!isFailurePass) && (!mModule->CheckProtection(checkMethod->mProtection, allowProtected, allowPrivate)))
continue; continue;
CheckMethod(curTypeInst, checkMethod, isFailurePass); CheckMethod(typeInstance, curTypeInst, checkMethod, isFailurePass);
} }
if (mBestMethodDef != NULL) if (mBestMethodDef != NULL)
@ -5632,7 +5649,7 @@ BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBou
} }
} }
methodMatcher.CheckMethod(curTypeInst, checkMethod, isFailurePass); methodMatcher.CheckMethod(NULL, curTypeInst, checkMethod, isFailurePass);
} }
if ((methodMatcher.mBestMethodDef != NULL) || (methodMatcher.mBackupMethodDef != NULL)) if ((methodMatcher.mBestMethodDef != NULL) || (methodMatcher.mBackupMethodDef != NULL))
@ -12243,7 +12260,7 @@ void BfExprEvaluator::CheckLocalMethods(BfAstNode* targetSrc, BfTypeInstance* ty
BfMethodDef* localMethodDef = NULL; BfMethodDef* localMethodDef = NULL;
if (ctxClosureInstanceInfo->mLocalMethodBindings.TryGetValue(_GetNodeId(), &localMethodDef)) if (ctxClosureInstanceInfo->mLocalMethodBindings.TryGetValue(_GetNodeId(), &localMethodDef))
{ {
methodMatcher.CheckMethod(mModule->mCurTypeInstance, localMethodDef, true); methodMatcher.CheckMethod(mModule->mCurTypeInstance, mModule->mCurTypeInstance, localMethodDef, true);
BF_ASSERT(methodMatcher.mBestMethodDef != NULL); BF_ASSERT(methodMatcher.mBestMethodDef != NULL);
return; return;
} }
@ -12263,7 +12280,7 @@ void BfExprEvaluator::CheckLocalMethods(BfAstNode* targetSrc, BfTypeInstance* ty
auto methodDef = mModule->GetLocalMethodDef(localMethod); auto methodDef = mModule->GetLocalMethodDef(localMethod);
if (methodDef->mMethodType == methodType) if (methodDef->mMethodType == methodType)
{ {
methodMatcher.CheckMethod(typeInst, methodDef, true); methodMatcher.CheckMethod(mModule->mCurTypeInstance, typeInst, methodDef, true);
if (methodMatcher.mBestMethodDef == methodDef) if (methodMatcher.mBestMethodDef == methodDef)
matchedLocalMethod = localMethod; matchedLocalMethod = localMethod;
} }
@ -16134,7 +16151,7 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr)
continue; continue;
methodMatcher.mCheckedKind = checkedKind; methodMatcher.mCheckedKind = checkedKind;
methodMatcher.CheckMethod(curCheckType, checkMethod, false); methodMatcher.CheckMethod(startCheckTypeInst, curCheckType, checkMethod, false);
if ((methodMatcher.mBestMethodDef == checkMethod) || if ((methodMatcher.mBestMethodDef == checkMethod) ||
((foundProp == NULL) && (methodMatcher.mBackupMethodDef == checkMethod))) ((foundProp == NULL) && (methodMatcher.mBackupMethodDef == checkMethod)))
@ -16492,7 +16509,7 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr,
{ {
if (!methodMatcher.IsMemberAccessible(checkType, operatorDef->mDeclaringType)) if (!methodMatcher.IsMemberAccessible(checkType, operatorDef->mDeclaringType))
continue; continue;
if (methodMatcher.CheckMethod(checkType, operatorDef, false)) if (methodMatcher.CheckMethod(NULL, checkType, operatorDef, false))
methodMatcher.mSelfType = entry.mSrcType; methodMatcher.mSelfType = entry.mSrcType;
} }
} }
@ -17673,7 +17690,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
if (!methodMatcher.IsMemberAccessible(checkType, operatorDef->mDeclaringType)) if (!methodMatcher.IsMemberAccessible(checkType, operatorDef->mDeclaringType))
continue; continue;
if (methodMatcher.CheckMethod(checkType, operatorDef, false)) if (methodMatcher.CheckMethod(NULL, checkType, operatorDef, false))
{ {
methodMatcher.mSelfType = entry.mSrcType; methodMatcher.mSelfType = entry.mSrcType;
if (operatorDef->mOperatorDeclaration->mBinOp == findBinaryOp) if (operatorDef->mOperatorDeclaration->mBinOp == findBinaryOp)
@ -17689,7 +17706,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
foundOp = true; foundOp = true;
for (auto oppositeOperatorDef : oppositeOperatorDefs) for (auto oppositeOperatorDef : oppositeOperatorDefs)
{ {
if (methodMatcher.CheckMethod(checkType, oppositeOperatorDef, false)) if (methodMatcher.CheckMethod(NULL, checkType, oppositeOperatorDef, false))
methodMatcher.mSelfType = entry.mSrcType; methodMatcher.mSelfType = entry.mSrcType;
} }
} }

View file

@ -170,7 +170,7 @@ public:
bool CheckType(BfTypeInstance* typeInstance, BfTypedValue target, bool isFailurePass); bool CheckType(BfTypeInstance* typeInstance, BfTypedValue target, bool isFailurePass);
void CheckOuterTypeStaticMethods(BfTypeInstance* typeInstance, bool isFailurePass); void CheckOuterTypeStaticMethods(BfTypeInstance* typeInstance, bool isFailurePass);
bool WantsCheckMethod(BfProtectionCheckFlags& flags, BfTypeInstance* startTypeInstance, BfTypeInstance* checkTypeInstance, BfMethodDef* methodDef); bool WantsCheckMethod(BfProtectionCheckFlags& flags, BfTypeInstance* startTypeInstance, BfTypeInstance* checkTypeInstance, BfMethodDef* methodDef);
bool CheckMethod(BfTypeInstance* typeInstance, BfMethodDef* checkMethod, bool isFailurePass); bool CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInstance* typeInstance, BfMethodDef* checkMethod, bool isFailurePass);
void TryDevirtualizeCall(BfTypedValue target, BfTypedValue* origTarget = NULL, BfTypedValue* staticResult = NULL); void TryDevirtualizeCall(BfTypedValue target, BfTypedValue* origTarget = NULL, BfTypedValue* staticResult = NULL);
}; };

View file

@ -9852,7 +9852,7 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
if ((!isFailurePass) && (!CheckProtection(checkMethod->mProtection, false, false))) if ((!isFailurePass) && (!CheckProtection(checkMethod->mProtection, false, false)))
continue; continue;
methodMatcher.CheckMethod(attrTypeInst, checkMethod, isFailurePass); methodMatcher.CheckMethod(NULL, attrTypeInst, checkMethod, isFailurePass);
} }
if ((methodMatcher.mBestMethodDef != NULL) || (methodMatcher.mBackupMethodDef != NULL)) if ((methodMatcher.mBestMethodDef != NULL) || (methodMatcher.mBackupMethodDef != NULL))
@ -20433,6 +20433,7 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo
{ {
auto declMethodInstance = (BfMethodInstance*)typeInstance->mVirtualMethodTable[virtualMethodMatchIdx].mDeclaringMethod; auto declMethodInstance = (BfMethodInstance*)typeInstance->mVirtualMethodTable[virtualMethodMatchIdx].mDeclaringMethod;
_AddVirtualDecl(declMethodInstance); _AddVirtualDecl(declMethodInstance);
setMethodInstance->mVirtualTableIdx = virtualMethodMatchIdx;
typeInstance->mVirtualMethodTable[virtualMethodMatchIdx].mImplementingMethod = setMethodInstance; typeInstance->mVirtualMethodTable[virtualMethodMatchIdx].mImplementingMethod = setMethodInstance;
} }
} }