Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/System.Linq.Dynamic.Core/Parser/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ namespace System.Linq.Dynamic.Core.Parser
{
internal static class Constants
{
public static readonly Expression TrueLiteral = Expression.Constant(true);
public static readonly Expression FalseLiteral = Expression.Constant(false);
public static readonly Expression NullLiteral = Expression.Constant(null);
public static bool IsNull(Expression exp)
{
return exp is ConstantExpression cExp && cExp.Value == null;
}
}
}
2 changes: 1 addition & 1 deletion src/System.Linq.Dynamic.Core/Parser/ExpressionHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ public Expression GenerateAndAlsoNotNullExpression(Expression sourceExpression)
expresssions.Reverse();

// Convert all expressions into '!= null'
var binaryExpressions = expresssions.Select(expression => Expression.NotEqual(expression, Constants.NullLiteral)).ToArray();
var binaryExpressions = expresssions.Select(expression => Expression.NotEqual(expression, Expression.Constant(null))).ToArray();

// Convert all binary expressions into `AndAlso(...)`
var andAlsoExpression = binaryExpressions[0];
Expand Down
18 changes: 9 additions & 9 deletions src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ Expression ParseComparisonOperator()
if (isEquality && (!left.Type.GetTypeInfo().IsValueType && !right.Type.GetTypeInfo().IsValueType || left.Type == typeof(Guid) && right.Type == typeof(Guid)))
{
// If left or right is NullLiteral, just continue. Else check if the types differ.
if (!(left == Constants.NullLiteral || right == Constants.NullLiteral) && left.Type != right.Type)
if (!(Constants.IsNull(left) || Constants.IsNull(right)) && left.Type != right.Type)
{
if (left.Type.IsAssignableFrom(right.Type))
{
Expand Down Expand Up @@ -1096,7 +1096,7 @@ Expression ParseFunctionNullPropagation()
{
var expressionTest = _expressionHelper.GenerateAndAlsoNotNullExpression(memberExpression);
var expressionIfTrue = memberExpression;
var expressionIfFalse = args.Length == 2 ? args[1] : Constants.NullLiteral;
var expressionIfFalse = args.Length == 2 ? args[1] : Expression.Constant(null);

return GenerateConditional(expressionTest, expressionIfTrue, expressionIfFalse, errorPos);
}
Expand Down Expand Up @@ -1170,12 +1170,12 @@ Expression GenerateConditional(Expression test, Expression expr1, Expression exp

if (expr1.Type != expr2.Type)
{
if ((expr1 == Constants.NullLiteral && expr2.Type.GetTypeInfo().IsValueType) || (expr2 == Constants.NullLiteral && expr1.Type.GetTypeInfo().IsValueType))
if ((Constants.IsNull(expr1) && expr2.Type.GetTypeInfo().IsValueType) || (Constants.IsNull(expr2) && expr1.Type.GetTypeInfo().IsValueType))
{
// If expr1 is a null constant and expr2 is a IsValueType:
// - create nullable constant from expr1 with type from expr2
// - convert expr2 to nullable
if (expr1 == Constants.NullLiteral && expr2.Type.GetTypeInfo().IsValueType)
if (Constants.IsNull(expr1) && expr2.Type.GetTypeInfo().IsValueType)
{
Type nullableType = typeof(Nullable<>).MakeGenericType(expr2.Type);
expr1 = Expression.Constant(null, nullableType);
Expand All @@ -1185,7 +1185,7 @@ Expression GenerateConditional(Expression test, Expression expr1, Expression exp
// If expr2 is a null constant and expr1 is a IsValueType:
// - create nullable constant from expr2 with type from expr1
// - convert expr1 to nullable
if (expr2 == Constants.NullLiteral && expr1.Type.GetTypeInfo().IsValueType)
if (Constants.IsNull(expr2) && expr1.Type.GetTypeInfo().IsValueType)
{
Type nullableType = typeof(Nullable<>).MakeGenericType(expr1.Type);
expr2 = Expression.Constant(null, nullableType);
Expand All @@ -1195,8 +1195,8 @@ Expression GenerateConditional(Expression test, Expression expr1, Expression exp
return Expression.Condition(test, expr1, expr2);
}

Expression expr1As2 = expr2 != Constants.NullLiteral ? _parsingConfig.ExpressionPromoter.Promote(expr1, expr2.Type, true, false) : null;
Expression expr2As1 = expr1 != Constants.NullLiteral ? _parsingConfig.ExpressionPromoter.Promote(expr2, expr1.Type, true, false) : null;
Expression expr1As2 = !Constants.IsNull(expr2) ? _parsingConfig.ExpressionPromoter.Promote(expr1, expr2.Type, true, false) : null;
Expression expr2As1 = !Constants.IsNull(expr1) ? _parsingConfig.ExpressionPromoter.Promote(expr2, expr1.Type, true, false) : null;
if (expr1As2 != null && expr2As1 == null)
{
expr1 = expr1As2;
Expand All @@ -1207,8 +1207,8 @@ Expression GenerateConditional(Expression test, Expression expr1, Expression exp
}
else
{
string type1 = expr1 != Constants.NullLiteral ? expr1.Type.Name : "null";
string type2 = expr2 != Constants.NullLiteral ? expr2.Type.Name : "null";
string type1 = !Constants.IsNull(expr1) ? expr1.Type.Name : "null";
string type2 = !Constants.IsNull(expr2) ? expr2.Type.Name : "null";
if (expr1As2 != null)
{
throw ParseError(errorPos, Res.BothTypesConvertToOther, type1, type2);
Expand Down
4 changes: 2 additions & 2 deletions src/System.Linq.Dynamic.Core/Parser/ExpressionPromoter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace System.Linq.Dynamic.Core.Parser
{
internal class ExpressionPromoter : IExpressionPromoter
public class ExpressionPromoter : IExpressionPromoter
{
/// <inheritdoc cref="IExpressionPromoter.Promote(Expression, Type, bool, bool)"/>
public virtual Expression Promote(Expression expr, Type type, bool exact, bool convertExpr)
Expand All @@ -17,7 +17,7 @@ public virtual Expression Promote(Expression expr, Type type, bool exact, bool c

if (ce != null)
{
if (ce == Constants.NullLiteral || ce.Value == null)
if (Constants.IsNull(ce))
{
if (!type.GetTypeInfo().IsValueType || TypeHelper.IsNullableType(type))
{
Expand Down
7 changes: 4 additions & 3 deletions src/System.Linq.Dynamic.Core/Parser/KeywordsHelper.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Linq.Expressions;

namespace System.Linq.Dynamic.Core.Parser
{
Expand All @@ -22,9 +23,9 @@ internal class KeywordsHelper : IKeywordsHelper

private readonly IDictionary<string, object> _keywords = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase)
{
{ "true", Constants.TrueLiteral },
{ "false", Constants.FalseLiteral },
{ "null", Constants.NullLiteral }
{ "true", Expression.Constant(true) },
{ "false", Expression.Constant(false) },
{ "null", Expression.Constant(null) }
};

public KeywordsHelper(ParsingConfig config)
Expand Down