Skip to content

Commit 7f45e14

Browse files
authored
Fix parsing a string literal with a dot (#687)
1 parent e0e2f9a commit 7f45e14

File tree

3 files changed

+462
-415
lines changed

3 files changed

+462
-415
lines changed

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

+27-2
Original file line numberDiff line numberDiff line change
@@ -802,8 +802,7 @@ private Expression ParsePrimaryStart()
802802
return ParseIdentifier();
803803

804804
case TokenId.StringLiteral:
805-
var expressionOrType = ParseStringLiteral(false);
806-
return expressionOrType.IsFirst ? expressionOrType.First : ParseTypeAccess(expressionOrType.Second, false);
805+
return ParseStringLiteralAsStringExpressionOrTypeExpression();
807806

808807
case TokenId.IntegerLiteral:
809808
return ParseIntegerLiteral();
@@ -819,6 +818,32 @@ private Expression ParsePrimaryStart()
819818
}
820819
}
821820

821+
private Expression ParseStringLiteralAsStringExpressionOrTypeExpression()
822+
{
823+
var clonedTextParser = _textParser.Clone();
824+
clonedTextParser.NextToken();
825+
826+
// Check if next token is a "(" or a "?(".
827+
// Used for casting like $"\"System.DateTime\"(Abc)" or $"\"System.DateTime\"?(Abc)".
828+
// In that case, the string value is NOT forced to stay a string.
829+
bool forceParseAsString = true;
830+
if (clonedTextParser.CurrentToken.Id == TokenId.OpenParen)
831+
{
832+
forceParseAsString = false;
833+
}
834+
else if (clonedTextParser.CurrentToken.Id == TokenId.Question)
835+
{
836+
clonedTextParser.NextToken();
837+
if (clonedTextParser.CurrentToken.Id == TokenId.OpenParen)
838+
{
839+
forceParseAsString = false;
840+
}
841+
}
842+
843+
var expressionOrType = ParseStringLiteral(forceParseAsString);
844+
return expressionOrType.IsFirst ? expressionOrType.First : ParseTypeAccess(expressionOrType.Second, false);
845+
}
846+
822847
private AnyOf<Expression, Type> ParseStringLiteral(bool forceParseAsString)
823848
{
824849
_textParser.ValidateToken(TokenId.StringLiteral);

0 commit comments

Comments
 (0)