Skip to content

Commit

Permalink
No longer move to the next token when parsing an is or as express…
Browse files Browse the repository at this point in the history
…ion (#289)
  • Loading branch information
metoule authored Jun 11, 2023
1 parent 65bdcba commit dfa3277
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 15 deletions.
35 changes: 21 additions & 14 deletions src/DynamicExpresso.Core/Parsing/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -481,8 +481,6 @@ private Expression ParseTypeTesting()
left = Expression.TypeAs(left, knownType);
else
throw CreateParseException(_token.pos, ErrorMessages.SyntaxError);

NextToken();
}

return left;
Expand Down Expand Up @@ -1443,6 +1441,22 @@ private bool TryParseKnownType(string name, out Type type)
var originalPos = _token.pos;
_arguments.TryGetKnownType(name, out type);

type = ParseKnownGenericType(name, type);
type = ParseTypeModifiers(type);

if (type == null)
{
// type name couldn't be parsed: restore position
SetTextPos(originalPos);
NextToken();
return false;
}

return true;
}

private Type ParseKnownGenericType(string name, Type type)
{
NextToken();
if (_token.id == TokenId.LessThan)
{
Expand All @@ -1451,7 +1465,7 @@ private bool TryParseKnownType(string name, out Type type)

// if no type was registered with the simple name, try the full generic name
if (type == null && !_arguments.TryGetKnownType(name + $"`{rank}", out type))
return false;
return null;

if (rank != type.GetGenericArguments().Length)
throw new ArgumentException($"The number of generic arguments provided doesn't equal the arity of the generic type definition.");
Expand All @@ -1463,17 +1477,7 @@ private bool TryParseKnownType(string name, out Type type)
NextToken();
}

type = ParseTypeModifiers(type);
if (type == null)
{
// type name couldn't be parsed: restore position
SetTextPos(originalPos);
NextToken();

return false;
}

return true;
return type;
}

// we found a known type identifier, check if it has some modifiers
Expand Down Expand Up @@ -3346,6 +3350,9 @@ private void NextToken()
}
if (_parsePosition == _expressionTextLength)
{
if (_token.id == TokenId.End)
throw new InvalidOperationException("NextToken called when already at the end of the expression");

t = TokenId.End;
break;
}
Expand Down
23 changes: 22 additions & 1 deletion test/DynamicExpresso.UnitTest/GithubIssues.cs
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,7 @@ public void GitHub_Issue_221_Case_insensitivity()

// case insensivity outside lambda expressions
Assert.IsFalse(interpreter.Eval<bool>("dateinthepast > now()")); // identifier
Assert.IsTrue(interpreter.Eval<bool>("dateinthepast is datetimeoffset)")); // known type
Assert.IsTrue(interpreter.Eval<bool>("dateinthepast is datetimeoffset")); // known type
Assert.IsFalse(interpreter.Eval<bool>("dateinthepast.isinfuture()")); // extension method

// ensure the case insensitivity option is also used in the lambda expression
Expand Down Expand Up @@ -728,6 +728,27 @@ public void GitHub_Issue_276()
var result = interpreter.Eval<bool>("((int?)5)>((double?)4)");
Assert.IsTrue(result);
}

[Test]
public void GitHub_Issue_287()
{
var interpreter = new Interpreter();
interpreter.Reference(typeof(IEnumerable<>));

object str = "test";
interpreter.SetVariable("str", str, typeof(object));

Assert.AreEqual(string.IsNullOrEmpty(str as string), interpreter.Eval("string.IsNullOrEmpty(str as string)"));
Assert.AreEqual(str is string, interpreter.Eval("str is string"));
Assert.AreEqual(str is int?, interpreter.Eval("str is int?"));
Assert.AreEqual(str is int[], interpreter.Eval("(str is int[])"));
Assert.AreEqual(str is int?[], interpreter.Eval("(str is int?[])"));
Assert.AreEqual(str is int?[][], interpreter.Eval("(str is int?[][])"));
Assert.AreEqual(str is IEnumerable<int>[][], interpreter.Eval("(str is IEnumerable<int>[][])"));
Assert.AreEqual(str is IEnumerable<int?>[][], interpreter.Eval("(str is IEnumerable<int?>[][])"));
Assert.AreEqual(str is IEnumerable<int[]>[][], interpreter.Eval("(str is IEnumerable<int[]>[][])"));
Assert.AreEqual(str is IEnumerable<int?[][]>[][], interpreter.Eval("(str is IEnumerable<int?[][]>[][])"));
}
}

internal static class GithubIssuesTestExtensionsMethods
Expand Down

0 comments on commit dfa3277

Please sign in to comment.