1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-15 06:44:10 +02:00

Improved method selection with failed method match

This commit is contained in:
Brian Fiete 2020-12-03 11:34:56 -08:00
parent b49e513494
commit 1b9921981e
2 changed files with 35 additions and 20 deletions

View file

@ -161,6 +161,7 @@ void BfMethodMatcher::Init(/*SizedArrayImpl<BfResolvedArg>& arguments, */BfSized
mActiveTypeDef = NULL; mActiveTypeDef = NULL;
mBestMethodDef = NULL; mBestMethodDef = NULL;
mBackupMethodDef = NULL; mBackupMethodDef = NULL;
mBackupMatchKind = BackupMatchKind_None;
mBestRawMethodInstance = NULL; mBestRawMethodInstance = NULL;
mBestMethodTypeInstance = NULL; mBestMethodTypeInstance = NULL;
mExplicitInterfaceCheck = NULL; mExplicitInterfaceCheck = NULL;
@ -1369,6 +1370,7 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
{ {
BP_ZONE("BfMethodMatcher::CheckMethod"); BP_ZONE("BfMethodMatcher::CheckMethod");
BackupMatchKind curMatchKind = BackupMatchKind_None;
bool hadMatch = false; bool hadMatch = false;
// Never consider overrides - they only get found at original method declaration // Never consider overrides - they only get found at original method declaration
@ -1790,6 +1792,19 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
{ {
if (!argTypedValue.HasType()) if (!argTypedValue.HasType())
{ {
// Check to see if this is the last argument and that it's a potential enum match
if ((wantType->IsEnum()) && (argIdx == mArguments.size() - 1))
{
if (auto memberRefExpr = BfNodeDynCast<BfMemberReferenceExpression>(mArguments[argIdx].mExpression))
{
if (memberRefExpr->mTarget == NULL)
{
// Is dot expression
curMatchKind = BackupMatchKind_PartialLastArgMatch;
}
}
}
goto NoMatch; goto NoMatch;
} }
else if (!mModule->CanCast(argTypedValue, wantType)) else if (!mModule->CanCast(argTypedValue, wantType))
@ -1937,30 +1952,20 @@ NoMatch:
if (mBestMethodDef != NULL) if (mBestMethodDef != NULL)
return false; return false;
/*if ((mHadExplicitGenericArguments) && (mBestMethodGenericArguments.size() != checkMethod->mGenericParams.size()))
return false;*/
if (mBackupMethodDef != NULL) if (mBackupMethodDef != NULL)
{
int prevParamDiff = (int)mBackupMethodDef->GetExplicitParamCount() - (int)mArguments.size();
int paramDiff = (int)checkMethod->GetExplicitParamCount() - (int)mArguments.size();
if ((prevParamDiff < 0) && (prevParamDiff > paramDiff))
return false;
if ((prevParamDiff >= 0) && ((paramDiff < 0) || (prevParamDiff < paramDiff)))
return false;
if (paramDiff == prevParamDiff)
{ {
if (argMatchCount < mBackupArgMatchCount) if (argMatchCount < mBackupArgMatchCount)
return false; return false;
else if (argMatchCount == mBackupArgMatchCount) else if (argMatchCount == mBackupArgMatchCount)
{ {
if (curMatchKind < mBackupMatchKind)
return false;
// We search from the most specific type, so don't prefer a less specific type // We search from the most specific type, so don't prefer a less specific type
if (mBestMethodTypeInstance != typeInstance) if (mBestMethodTypeInstance != typeInstance)
return false; return false;
} }
} }
}
if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo)) if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo))
{ {
@ -1971,6 +1976,7 @@ NoMatch:
} }
} }
mBackupMatchKind = curMatchKind;
mBackupMethodDef = checkMethod; mBackupMethodDef = checkMethod;
mBackupArgMatchCount = argMatchCount; mBackupArgMatchCount = argMatchCount;
// Lie temporarily to store at least one candidate (but mBestMethodDef is still NULL) // Lie temporarily to store at least one candidate (but mBestMethodDef is still NULL)

View file

@ -152,6 +152,14 @@ public:
MatchFailKind_CheckedMismatch MatchFailKind_CheckedMismatch
}; };
enum BackupMatchKind
{
BackupMatchKind_None,
BackupMatchKind_TooManyArgs,
BackupMatchKind_EarlyMismatch,
BackupMatchKind_PartialLastArgMatch
};
public: public:
BfAstNode* mTargetSrc; BfAstNode* mTargetSrc;
BfTypedValue mTarget; BfTypedValue mTarget;
@ -181,6 +189,7 @@ public:
BfType* mSelfType; // Only when matching interfaces when 'Self' needs to refer back to the implementing type BfType* mSelfType; // Only when matching interfaces when 'Self' needs to refer back to the implementing type
BfMethodDef* mBackupMethodDef; BfMethodDef* mBackupMethodDef;
BackupMatchKind mBackupMatchKind;
int mBackupArgMatchCount; int mBackupArgMatchCount;
BfMethodDef* mBestMethodDef; BfMethodDef* mBestMethodDef;
BfTypeInstance* mBestMethodTypeInstance; BfTypeInstance* mBestMethodTypeInstance;