Skip to content

Commit dfa3277

Browse files
authored
No longer move to the next token when parsing an is or as expression (#289)
1 parent 65bdcba commit dfa3277

File tree

2 files changed

+43
-15
lines changed

2 files changed

+43
-15
lines changed

src/DynamicExpresso.Core/Parsing/Parser.cs

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -481,8 +481,6 @@ private Expression ParseTypeTesting()
481481
left = Expression.TypeAs(left, knownType);
482482
else
483483
throw CreateParseException(_token.pos, ErrorMessages.SyntaxError);
484-
485-
NextToken();
486484
}
487485

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

1444+
type = ParseKnownGenericType(name, type);
1445+
type = ParseTypeModifiers(type);
1446+
1447+
if (type == null)
1448+
{
1449+
// type name couldn't be parsed: restore position
1450+
SetTextPos(originalPos);
1451+
NextToken();
1452+
return false;
1453+
}
1454+
1455+
return true;
1456+
}
1457+
1458+
private Type ParseKnownGenericType(string name, Type type)
1459+
{
14461460
NextToken();
14471461
if (_token.id == TokenId.LessThan)
14481462
{
@@ -1451,7 +1465,7 @@ private bool TryParseKnownType(string name, out Type type)
14511465

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

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

1466-
type = ParseTypeModifiers(type);
1467-
if (type == null)
1468-
{
1469-
// type name couldn't be parsed: restore position
1470-
SetTextPos(originalPos);
1471-
NextToken();
1472-
1473-
return false;
1474-
}
1475-
1476-
return true;
1480+
return type;
14771481
}
14781482

14791483
// we found a known type identifier, check if it has some modifiers
@@ -3346,6 +3350,9 @@ private void NextToken()
33463350
}
33473351
if (_parsePosition == _expressionTextLength)
33483352
{
3353+
if (_token.id == TokenId.End)
3354+
throw new InvalidOperationException("NextToken called when already at the end of the expression");
3355+
33493356
t = TokenId.End;
33503357
break;
33513358
}

test/DynamicExpresso.UnitTest/GithubIssues.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ public void GitHub_Issue_221_Case_insensitivity()
510510

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

516516
// ensure the case insensitivity option is also used in the lambda expression
@@ -728,6 +728,27 @@ public void GitHub_Issue_276()
728728
var result = interpreter.Eval<bool>("((int?)5)>((double?)4)");
729729
Assert.IsTrue(result);
730730
}
731+
732+
[Test]
733+
public void GitHub_Issue_287()
734+
{
735+
var interpreter = new Interpreter();
736+
interpreter.Reference(typeof(IEnumerable<>));
737+
738+
object str = "test";
739+
interpreter.SetVariable("str", str, typeof(object));
740+
741+
Assert.AreEqual(string.IsNullOrEmpty(str as string), interpreter.Eval("string.IsNullOrEmpty(str as string)"));
742+
Assert.AreEqual(str is string, interpreter.Eval("str is string"));
743+
Assert.AreEqual(str is int?, interpreter.Eval("str is int?"));
744+
Assert.AreEqual(str is int[], interpreter.Eval("(str is int[])"));
745+
Assert.AreEqual(str is int?[], interpreter.Eval("(str is int?[])"));
746+
Assert.AreEqual(str is int?[][], interpreter.Eval("(str is int?[][])"));
747+
Assert.AreEqual(str is IEnumerable<int>[][], interpreter.Eval("(str is IEnumerable<int>[][])"));
748+
Assert.AreEqual(str is IEnumerable<int?>[][], interpreter.Eval("(str is IEnumerable<int?>[][])"));
749+
Assert.AreEqual(str is IEnumerable<int[]>[][], interpreter.Eval("(str is IEnumerable<int[]>[][])"));
750+
Assert.AreEqual(str is IEnumerable<int?[][]>[][], interpreter.Eval("(str is IEnumerable<int?[][]>[][])"));
751+
}
731752
}
732753

733754
internal static class GithubIssuesTestExtensionsMethods

0 commit comments

Comments
 (0)