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:
parent
b49e513494
commit
1b9921981e
2 changed files with 35 additions and 20 deletions
|
@ -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,13 +1370,14 @@ 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
|
||||||
// mBypassVirtual gets set when we are doing an explicit "base" call, or when we are a struct --
|
// mBypassVirtual gets set when we are doing an explicit "base" call, or when we are a struct --
|
||||||
// because on structs we know the exact type
|
// because on structs we know the exact type
|
||||||
if ((checkMethod->mIsOverride) && (!mBypassVirtual) && (!typeInstance->IsValueType()))
|
if ((checkMethod->mIsOverride) && (!mBypassVirtual) && (!typeInstance->IsValueType()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
mMethodCheckCount++;
|
mMethodCheckCount++;
|
||||||
|
|
||||||
|
@ -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,29 +1952,19 @@ 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();
|
if (argMatchCount < mBackupArgMatchCount)
|
||||||
int paramDiff = (int)checkMethod->GetExplicitParamCount() - (int)mArguments.size();
|
|
||||||
if ((prevParamDiff < 0) && (prevParamDiff > paramDiff))
|
|
||||||
return false;
|
return false;
|
||||||
if ((prevParamDiff >= 0) && ((paramDiff < 0) || (prevParamDiff < paramDiff)))
|
else if (argMatchCount == mBackupArgMatchCount)
|
||||||
return false;
|
|
||||||
|
|
||||||
if (paramDiff == prevParamDiff)
|
|
||||||
{
|
{
|
||||||
if (argMatchCount < mBackupArgMatchCount)
|
if (curMatchKind < mBackupMatchKind)
|
||||||
return false;
|
return false;
|
||||||
else if (argMatchCount == mBackupArgMatchCount)
|
|
||||||
{
|
// 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)
|
||||||
|
@ -2271,7 +2277,7 @@ bool BfMethodMatcher::CheckType(BfTypeInstance* typeInstance, BfTypedValue targe
|
||||||
if (mBestMethodDef == NULL)
|
if (mBestMethodDef == NULL)
|
||||||
{
|
{
|
||||||
// FAILED, but select the first method which will fire an actual error on param type matching
|
// FAILED, but select the first method which will fire an actual error on param type matching
|
||||||
mBestMethodDef = mBackupMethodDef;
|
mBestMethodDef = mBackupMethodDef;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((mBestMethodDef == NULL) && (!target) && (mAllowImplicitThis)) ||
|
if (((mBestMethodDef == NULL) && (!target) && (mAllowImplicitThis)) ||
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue