From d03a4432795fc81e976afa3af2ed927c023d26fc Mon Sep 17 00:00:00 2001 From: metoule Date: Sat, 17 Aug 2024 18:09:19 +0200 Subject: [PATCH 1/3] No longer try to parse a generic type if there's no possible generic definition candidate in the known types. Fix #314 --- src/DynamicExpresso.Core/ParserArguments.cs | 10 ++++++++++ src/DynamicExpresso.Core/Parsing/Parser.cs | 9 +++++++-- test/DynamicExpresso.UnitTest/GithubIssues.cs | 13 +++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/DynamicExpresso.Core/ParserArguments.cs b/src/DynamicExpresso.Core/ParserArguments.cs index 0f5d8649..1105cff2 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 definition type 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 b606b961..81e783f4 100644 --- a/src/DynamicExpresso.Core/Parsing/Parser.cs +++ b/src/DynamicExpresso.Core/Parsing/Parser.cs @@ -1440,9 +1440,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 010292ee..c2b1db61 100644 --- a/test/DynamicExpresso.UnitTest/GithubIssues.cs +++ b/test/DynamicExpresso.UnitTest/GithubIssues.cs @@ -819,6 +819,19 @@ public void GitHub_Issue_305() } #endregion + + [Test] + public void GitHub_Issue_314() + { + var interpreter = new Interpreter(); + var parameters = new[] { new Parameter("a", 1) }; + + var exception1 = Assert.Throws(() => interpreter.Eval("a < 1 || b < 1 ", parameters)); + Assert.AreEqual("b", exception1.Identifier); + + var exception2 = Assert.Throws(() => interpreter.Eval("a < 1 || b > 1 ", parameters)); + Assert.AreEqual("b", exception2.Identifier); + } } internal static class GithubIssuesTestExtensionsMethods From 1936db1c619924c457c2c9c51ebe11a1b326688f Mon Sep 17 00:00:00 2001 From: metoule Date: Sat, 17 Aug 2024 18:13:33 +0200 Subject: [PATCH 2/3] Simplify tests --- test/DynamicExpresso.UnitTest/GithubIssues.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/DynamicExpresso.UnitTest/GithubIssues.cs b/test/DynamicExpresso.UnitTest/GithubIssues.cs index c2b1db61..baf24953 100644 --- a/test/DynamicExpresso.UnitTest/GithubIssues.cs +++ b/test/DynamicExpresso.UnitTest/GithubIssues.cs @@ -824,12 +824,11 @@ public void GitHub_Issue_305() public void GitHub_Issue_314() { var interpreter = new Interpreter(); - var parameters = new[] { new Parameter("a", 1) }; - var exception1 = Assert.Throws(() => interpreter.Eval("a < 1 || b < 1 ", parameters)); + var exception1 = Assert.Throws(() => interpreter.Eval("b < 1")); Assert.AreEqual("b", exception1.Identifier); - var exception2 = Assert.Throws(() => interpreter.Eval("a < 1 || b > 1 ", parameters)); + var exception2 = Assert.Throws(() => interpreter.Eval("b > 1")); Assert.AreEqual("b", exception2.Identifier); } } From aa0a545feec603b2290fafb4e9453794cca42e88 Mon Sep 17 00:00:00 2001 From: metoule Date: Sat, 17 Aug 2024 18:16:03 +0200 Subject: [PATCH 3/3] Typo --- src/DynamicExpresso.Core/ParserArguments.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DynamicExpresso.Core/ParserArguments.cs b/src/DynamicExpresso.Core/ParserArguments.cs index 1105cff2..c4b68407 100644 --- a/src/DynamicExpresso.Core/ParserArguments.cs +++ b/src/DynamicExpresso.Core/ParserArguments.cs @@ -77,7 +77,7 @@ public bool TryGetKnownType(string name, out Type type) } /// - /// Returns true if the known types contain a generic definition type with the given name + any arity (e.g. name`1). + /// 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) {