diff --git a/src/DynamicExpresso.Core/ParserArguments.cs b/src/DynamicExpresso.Core/ParserArguments.cs index 0f5d864..c4b6840 100644 --- a/src/DynamicExpresso.Core/ParserArguments.cs +++ b/src/DynamicExpresso.Core/ParserArguments.cs @@ -5,6 +5,7 @@ using System.Linq.Expressions; using System.Reflection; using DynamicExpresso.Exceptions; +using System.Text.RegularExpressions; namespace DynamicExpresso { @@ -75,6 +76,15 @@ public bool TryGetKnownType(string name, out Type type) return false; } + /// + /// Returns true if the known types contain a generic type definition with the given name + any arity (e.g. name`1). + /// + internal bool HasKnownGenericTypeDefinition(string name) + { + var regex = new Regex("^" + name + "`\\d+$"); + return Settings.KnownTypes.Values.Any(refType => regex.IsMatch(refType.Name) && refType.Type.IsGenericTypeDefinition); + } + public bool TryGetIdentifier(string name, out Expression expression) { Identifier identifier; diff --git a/src/DynamicExpresso.Core/Parsing/Parser.cs b/src/DynamicExpresso.Core/Parsing/Parser.cs index 282526e..5118524 100644 --- a/src/DynamicExpresso.Core/Parsing/Parser.cs +++ b/src/DynamicExpresso.Core/Parsing/Parser.cs @@ -1399,9 +1399,14 @@ private bool TryParseKnownType(string name, out Type type) { // if the type is unknown, we need to restart parsing var originalPos = _token.pos; - _arguments.TryGetKnownType(name, out type); - type = ParseKnownGenericType(name, type); + // the name might reference a generic type, with an aliased name (e.g. List = MyList instead of List`1) + // it can also reference a generic type for which we don't know the arity yet (and therefore the name doesn't contain the `n suffix) + if (_arguments.TryGetKnownType(name, out type) || _arguments.HasKnownGenericTypeDefinition(name)) + { + type = ParseKnownGenericType(name, type); + } + type = ParseTypeModifiers(type); if (type == null) diff --git a/test/DynamicExpresso.UnitTest/GithubIssues.cs b/test/DynamicExpresso.UnitTest/GithubIssues.cs index 0edcc81..bb0f544 100644 --- a/test/DynamicExpresso.UnitTest/GithubIssues.cs +++ b/test/DynamicExpresso.UnitTest/GithubIssues.cs @@ -836,6 +836,18 @@ public void GitHub_Issue_311() // It works if we cast to int Assert.AreEqual("AA", interpreter2.Eval("a.Substring((int)0, (int)2)")); } + + [Test] + public void GitHub_Issue_314() + { + var interpreter = new Interpreter(); + + var exception1 = Assert.Throws(() => interpreter.Eval("b < 1")); + Assert.AreEqual("b", exception1.Identifier); + + var exception2 = Assert.Throws(() => interpreter.Eval("b > 1")); + Assert.AreEqual("b", exception2.Identifier); + } } internal static class GithubIssuesTestExtensionsMethods