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

Fixed generic extension methods with primitive 'this'

This commit is contained in:
Brian Fiete 2020-12-01 11:35:10 -08:00
parent d976ea77e9
commit 222d030aa4
3 changed files with 42 additions and 2 deletions

View file

@ -1574,7 +1574,12 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
{ {
BfTypedValue argTypedValue; BfTypedValue argTypedValue;
if (argIdx == -1) if (argIdx == -1)
{
if (mOrigTarget)
argTypedValue = mOrigTarget;
else
argTypedValue = mTarget; argTypedValue = mTarget;
}
else else
argTypedValue = ResolveArgTypedValue(mArguments[argIdx], checkType, genericArgumentsSubstitute, origCheckType); argTypedValue = ResolveArgTypedValue(mArguments[argIdx], checkType, genericArgumentsSubstitute, origCheckType);
if (!argTypedValue.IsUntypedValue()) if (!argTypedValue.IsUntypedValue())
@ -7292,6 +7297,7 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
BfTypeInstance* curTypeInst = targetTypeInst; BfTypeInstance* curTypeInst = targetTypeInst;
BfMethodMatcher methodMatcher(targetSrc, mModule, methodName, argValues.mResolvedArgs, methodGenericArguments); BfMethodMatcher methodMatcher(targetSrc, mModule, methodName, argValues.mResolvedArgs, methodGenericArguments);
methodMatcher.mOrigTarget = origTarget;
methodMatcher.mTarget = target; methodMatcher.mTarget = target;
methodMatcher.mCheckedKind = checkedKind; methodMatcher.mCheckedKind = checkedKind;
methodMatcher.mAllowImplicitThis = allowImplicitThis; methodMatcher.mAllowImplicitThis = allowImplicitThis;
@ -19674,6 +19680,8 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
bool isComparison = (binaryOp >= BfBinaryOp_Equality) && (binaryOp <= BfBinaryOp_LessThanOrEqual); bool isComparison = (binaryOp >= BfBinaryOp_Equality) && (binaryOp <= BfBinaryOp_LessThanOrEqual);
BfBinaryOp oppositeBinaryOp = BfGetOppositeBinaryOp(findBinaryOp); BfBinaryOp oppositeBinaryOp = BfGetOppositeBinaryOp(findBinaryOp);
BfBinaryOp flippedBinaryOp = BfGetFlippedBinaryOp(findBinaryOp);
BfBinaryOp flippedOppositeBinaryOp = BfGetFlippedBinaryOp(oppositeBinaryOp);
for (int pass = 0; pass < 2; pass++) for (int pass = 0; pass < 2; pass++)
{ {
@ -19901,6 +19909,14 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
works = true; works = true;
} }
} }
if ((flippedBinaryOp != BfBinaryOp_None) && (opConstraint.mBinaryOp == flippedBinaryOp))
{
if ((mModule->CanCast(args[1].mTypedValue, opConstraint.mLeftType)) &&
(mModule->CanCast(args[0].mTypedValue, opConstraint.mRightType)))
{
works = true;
}
}
if (((oppositeBinaryOp != BfBinaryOp_None) && (opConstraint.mBinaryOp == oppositeBinaryOp)) || if (((oppositeBinaryOp != BfBinaryOp_None) && (opConstraint.mBinaryOp == oppositeBinaryOp)) ||
(opConstraint.mBinaryOp == BfBinaryOp_Compare)) (opConstraint.mBinaryOp == BfBinaryOp_Compare))
@ -19911,6 +19927,14 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
works = true; works = true;
} }
} }
if ((flippedOppositeBinaryOp != BfBinaryOp_None) && (opConstraint.mBinaryOp == flippedOppositeBinaryOp))
{
if ((mModule->CanCast(args[1].mTypedValue, opConstraint.mRightType)) &&
(mModule->CanCast(args[0].mTypedValue, opConstraint.mLeftType)))
{
works = true;
}
}
if ((isComparison) && (opConstraint.mBinaryOp == BfBinaryOp_Compare)) if ((isComparison) && (opConstraint.mBinaryOp == BfBinaryOp_Compare))
{ {

View file

@ -154,6 +154,7 @@ public:
public: public:
BfAstNode* mTargetSrc; BfAstNode* mTargetSrc;
BfTypedValue mTarget; BfTypedValue mTarget;
BfTypedValue mOrigTarget;
BfModule* mModule; BfModule* mModule;
BfTypeDef* mActiveTypeDef; BfTypeDef* mActiveTypeDef;
String mMethodName; String mMethodName;

View file

@ -42,11 +42,26 @@ namespace Tests
iList.Add(100); iList.Add(100);
Test.Assert(iList.Total() == 123); Test.Assert(iList.Total() == 123);
float a = 1.2f;
float b = 2.3f;
Test.Assert(a.CompareIt(b) < 0);
} }
} }
static static
{ {
public static int CompareIt<T>(this T self, T other)
where bool: operator T < T
{
if(self < other)
return -1;
else if(self > other)
return 1;
return 0;
}
public static T Total<T>(this List<T> list) where T : operator T + T public static T Total<T>(this List<T> list) where T : operator T + T
{ {
T total = default; T total = default;