Skip to content

Commit cc1fbe2

Browse files
committed
NodaTime? [wip]
1 parent b1a64ff commit cc1fbe2

File tree

3 files changed

+243
-132
lines changed

3 files changed

+243
-132
lines changed

src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2505,9 +2505,57 @@ private bool TryGetOverloadedImplicitOperator(TokenId tokenId, ref Expression le
25052505
return overloadedImplicitOperatorFound;
25062506
}
25072507

2508+
private bool TryGetOverloadedExplicitOperator(TokenId tokenId, ref Expression left, ref Expression right)
2509+
{
2510+
const string methodName = "op_Explicit";
2511+
//if (tokenId is not (TokenId.Ampersand or TokenId.DoubleAmpersand or TokenId.Bar or TokenId.DoubleBar))
2512+
//{
2513+
// return false;
2514+
//}
2515+
2516+
Expression? expression = null;
2517+
var overloadedExplicitOperatorFound = false;
2518+
2519+
// Try to find the "op_Explicit" method on the left which takes the left as parameter and returns the type.
2520+
var leftType = left.Type;
2521+
var isNullableLeftType = TypeHelper.TryGetNonNullableType(leftType, out var nonNullableLeftType);
2522+
var args = new[] { left };
2523+
if (_methodFinder.FindMethod(leftType, methodName, true, ref expression, ref args, out var methodBaseLeft) > 0 && methodBaseLeft is MethodInfo methodInfoLeft && methodInfoLeft.ReturnType == nonNullableLeftType)
2524+
{
2525+
//if (isNullableLeftType)
2526+
//{
2527+
// left = Expression.Convert(left, leftType);
2528+
//}
2529+
//left = Expression.Call(methodInfoLeft, left);
2530+
2531+
left = Expression.Convert(left, nonNullableLeftType, methodInfoLeft);
2532+
2533+
overloadedExplicitOperatorFound = true;
2534+
}
2535+
2536+
// Try to find the "op_Explicit" method on the right which takes the right as parameter and returns the type.
2537+
var rightType = right.Type;
2538+
var rightTypeIsNullable = TypeHelper.TryGetNonNullableType(rightType, out var nonNullableRightType);
2539+
var argsRight = new[] { right };
2540+
if (_methodFinder.FindMethod(rightType, methodName, true, ref expression, ref argsRight, out var methodBaseRight) > 0 && methodBaseRight is MethodInfo methodInfoRight && methodInfoRight.ReturnType == nonNullableRightType)
2541+
{
2542+
//if (rightTypeIsNullable)
2543+
//{
2544+
// right = Expression.Convert(right, rightType);
2545+
//}
2546+
//right = Expression.Call(methodInfoRight, right);
2547+
2548+
right = Expression.Convert(right, nonNullableRightType, methodInfoRight);
2549+
2550+
overloadedExplicitOperatorFound = true;
2551+
}
2552+
2553+
return overloadedExplicitOperatorFound;
2554+
}
2555+
25082556
private void CheckAndPromoteOperands(Type signatures, TokenId opId, string opName, ref Expression left, ref Expression right, int errorPos)
25092557
{
2510-
Expression[] args = { left, right };
2558+
Expression[] args = [left, right];
25112559

25122560
// 1. Try to find the Equality/Inequality operator
25132561
// 2. Try to find the method with the given signature
@@ -2525,6 +2573,12 @@ private void CheckAndPromoteOperands(Type signatures, TokenId opId, string opNam
25252573
return;
25262574
}
25272575

2576+
// 4. Try to find the Explicit operator
2577+
if (TryGetOverloadedExplicitOperator(opId, ref left, ref right))
2578+
{
2579+
return;
2580+
}
2581+
25282582
throw IncompatibleOperandsError(opName, left, right, errorPos);
25292583
}
25302584

src/System.Linq.Dynamic.Core/Parser/TypeHelper.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,18 @@ public static Type GetNonNullableType(Type type)
459459
return IsNullableType(type) ? type.GetTypeInfo().GetGenericTypeArguments()[0] : type;
460460
}
461461

462+
public static bool TryGetNonNullableType(Type type, [NotNullWhen(true)] out Type nullableType)
463+
{
464+
if (!IsNullableType(type))
465+
{
466+
nullableType = type;
467+
return false;
468+
}
469+
470+
nullableType = type.GetTypeInfo().GetGenericTypeArguments()[0];
471+
return true;
472+
}
473+
462474
public static Type GetUnderlyingType(Type type)
463475
{
464476
Type[] genericTypeArguments = type.GetGenericArguments();

0 commit comments

Comments
 (0)