Skip to content

Commit

Permalink
Update function argument parsing for strings (#758)
Browse files Browse the repository at this point in the history
  • Loading branch information
StefH authored Nov 28, 2023
1 parent 166eada commit 59e029b
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 10 deletions.
12 changes: 7 additions & 5 deletions src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -914,6 +914,13 @@ private AnyOf<Expression, Type> ParseStringLiteral(bool forceParseAsString)
}
}

// While the next token is also a string, keep concatenating these strings and get next token
while (_textParser.CurrentToken.Id == TokenId.StringLiteral)
{
stringValue += _textParser.CurrentToken.Text;
_textParser.NextToken();
}

return ConstantExpressionHelper.CreateLiteral(stringValue, stringValue);
}

Expand Down Expand Up @@ -2188,11 +2195,6 @@ private Expression[] ParseArguments()
_textParser.NextToken();
}

//if (argList.OfType<ParameterExpression>().Count() > 1)
//{
// throw ParseError(_textParser.CurrentToken.Pos, Res.OutVariableSingleRequired);
//}

return argList.ToArray();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,11 @@ public static class StaticHelper
{
return Guid.NewGuid();
}

public static string Filter(string filter)
{
return filter;
}
}

public class TestCustomTypeProvider : AbstractDynamicLinqCustomTypeProvider, IDynamicLinkCustomTypeProvider
Expand Down Expand Up @@ -1379,14 +1384,58 @@ public void DynamicExpressionParser_ParseLambda_Operator_Less_Greater_With_Guids

// Act
var lambda = DynamicExpressionParser.ParseLambda(config, typeof(User), null, expressionText, user);
var guidLambda = lambda as Expression<Func<User, Guid>>;
Assert.NotNull(guidLambda);
var guidLambda = (Expression<Func<User, Guid>>)lambda;

var del = lambda.Compile();
var result = (Guid)del.DynamicInvoke(user);
var del = guidLambda.Compile();
var result = (Guid?)del.DynamicInvoke(user);

// Assert
Assert.Equal(anotherId, result);
result.Should().Be(anotherId);
}

[Fact]
public void DynamicExpressionParser_ParseLambda_CustomType_Method_With_ExpressionString()
{
// Arrange
var config = new ParsingConfig
{
CustomTypeProvider = new TestCustomTypeProvider()
};

var user = new User();

// Act : char
var expressionTextChar = "StaticHelper.Filter(\"C == 'x'\")";
var lambdaChar = DynamicExpressionParser.ParseLambda(config, typeof(User), null, expressionTextChar, user);
var funcChar = (Expression<Func<User, string>>)lambdaChar;

var delegateChar = funcChar.Compile();
var resultChar = (string?)delegateChar.DynamicInvoke(user);

// Assert : int
resultChar.Should().Be("C == 'x'");

// Act : int
var expressionTextIncome = "StaticHelper.Filter(\"Income == 5\")";
var lambdaIncome = DynamicExpressionParser.ParseLambda(config, typeof(User), null, expressionTextIncome, user);
var funcIncome = (Expression<Func<User, string>>)lambdaIncome;

var delegateIncome = funcIncome.Compile();
var resultIncome = (string?)delegateIncome.DynamicInvoke(user);

// Assert : int
resultIncome.Should().Be("Income == 5");

// Act : string
var expressionTextUserName = "StaticHelper.Filter(\"UserName == \"\"x\"\"\")";
var lambdaUserName = DynamicExpressionParser.ParseLambda(config, typeof(User), null, expressionTextUserName, user);
var funcUserName = (Expression<Func<User, string>>)lambdaUserName;

var delegateUserName = funcUserName.Compile();
var resultUserName = (string?)delegateUserName.DynamicInvoke(user);

// Assert : string
resultUserName.Should().Be(@"UserName == ""x""""""");
}

[Theory]
Expand Down
2 changes: 2 additions & 0 deletions test/System.Linq.Dynamic.Core.Tests/Helpers/Models/User.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ public class User

public int Income { get; set; }

public char C { get; set; }

public UserProfile Profile { get; set; }

public UserState State { get; set; }
Expand Down

0 comments on commit 59e029b

Please sign in to comment.