Skip to content

Commit

Permalink
No longer try to parse a generic type if there's no possible candidat…
Browse files Browse the repository at this point in the history
…es (#315)

* No longer try to parse a generic type if there's no possible generic definition candidate in the known types.
Fix #314
  • Loading branch information
metoule committed Aug 19, 2024
1 parent 53d14df commit 80031cb
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 2 deletions.
10 changes: 10 additions & 0 deletions src/DynamicExpresso.Core/ParserArguments.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Linq.Expressions;
using System.Reflection;
using DynamicExpresso.Exceptions;
using System.Text.RegularExpressions;

namespace DynamicExpresso
{
Expand Down Expand Up @@ -75,6 +76,15 @@ public bool TryGetKnownType(string name, out Type type)
return false;
}

/// <summary>
/// Returns true if the known types contain a generic type definition with the given name + any arity (e.g. name`1).
/// </summary>
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;
Expand Down
9 changes: 7 additions & 2 deletions src/DynamicExpresso.Core/Parsing/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T> = 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)
Expand Down
12 changes: 12 additions & 0 deletions test/DynamicExpresso.UnitTest/GithubIssues.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<UnknownIdentifierException>(() => interpreter.Eval("b < 1"));
Assert.AreEqual("b", exception1.Identifier);

var exception2 = Assert.Throws<UnknownIdentifierException>(() => interpreter.Eval("b > 1"));
Assert.AreEqual("b", exception2.Identifier);
}
}

internal static class GithubIssuesTestExtensionsMethods
Expand Down

0 comments on commit 80031cb

Please sign in to comment.