Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No longer move to the next token when parsing an is or as expression #289

Merged
merged 4 commits into from
Jun 11, 2023
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
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();
davideicardi marked this conversation as resolved.
Show resolved Hide resolved
}

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);
davideicardi marked this conversation as resolved.
Show resolved Hide resolved
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");
davideicardi marked this conversation as resolved.
Show resolved Hide resolved

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
davideicardi marked this conversation as resolved.
Show resolved Hide resolved
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