Skip to content

Commit aa3a753

Browse files
committed
IEnumerable Initializer (works for Lists)
1 parent dbc904e commit aa3a753

File tree

2 files changed

+54
-7
lines changed

2 files changed

+54
-7
lines changed

CodingSeb.ExpressionEvaluator.Tests/ExpressionEvaluatorTests.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,15 @@ public void TypeTesting(string expression, Type type)
496496
[TestCase("new ClassForTest2(15).Value1", ExpectedResult = 15, Category = "Create instance with new Keyword")]
497497
[TestCase("new CodingSeb.ExpressionEvaluator.Tests.OtherNamespace.ClassInOtherNameSpace1().Value1", ExpectedResult = 26, Category = "Create instance with new Keyword,Inline namespace")]
498498
[TestCase("new Regex(@\"\\w*[n]\\w*\").Match(\"Which word contains the desired letter ?\").Value", ExpectedResult = "contains", Category = "Create instance with new Keyword")]
499+
[TestCase("new List<string>(){ \"Hello\", \"Test\" }.GetType()", ExpectedResult = typeof(List<string>), Category = "Create instance with new Keyword, Collection Initializer")]
500+
[TestCase("new List<string>(){ \"Hello\", \"Test\" }.Count", ExpectedResult = 2, Category = "Create instance with new Keyword, Collection Initializer")]
501+
[TestCase("new List<string>(){ \"Hello\", \"Test\" }[0]", ExpectedResult = "Hello", Category = "Create instance with new Keyword, Collection Initializer")]
502+
[TestCase("new List<string>(){ \"Hello\", \"Test\" }[1]", ExpectedResult = "Test", Category = "Create instance with new Keyword, Collection Initializer")]
503+
[TestCase("new List<string>{ \"Hello\", \"Test\" }.GetType()", ExpectedResult = typeof(List<string>), Category = "Create instance with new Keyword, Collection Initializer")]
504+
[TestCase("new List<string>{ \"Hello\", \"Test\" }.Count", ExpectedResult = 2, Category = "Create instance with new Keyword, Collection Initializer")]
505+
[TestCase("new List<string>{ \"Hello\", \"Test\" }[0]", ExpectedResult = "Hello", Category = "Create instance with new Keyword, Collection Initializer")]
506+
[TestCase("new List<string>{ \"Hello\", \"Test\" }[1]", ExpectedResult = "Test", Category = "Create instance with new Keyword, Collection Initializer")]
507+
499508
#endregion
500509

501510
#region Logical And Shift Operators

CodingSeb.ExpressionEvaluator/ExpressionEvaluator.cs

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
/******************************************************************************************************
22
Title : ExpressionEvaluator (https://github.com/codingseb/ExpressionEvaluator)
3-
Version : 1.3.2.2
3+
Version : 1.3.2.3
44
(if last digit (the forth) is not a zero, the version is an intermediate version and can be unstable)
55
66
Author : Coding Seb
77
Licence : MIT (https://github.com/codingseb/ExpressionEvaluator/blob/master/LICENSE.md)
88
*******************************************************************************************************/
99

1010
using System;
11+
using System.Collections;
1112
using System.Collections.Generic;
1213
using System.ComponentModel;
1314
using System.Dynamic;
@@ -51,7 +52,7 @@ public class ExpressionEvaluator
5152

5253

5354
// Depending on OptionInlineNamespacesEvaluationActive. Initialized in constructor
54-
private string InstanceCreationWithNewKeywordRegexPattern { get { return $@"^new\s+(?<name>[{ diactiticsKeywordsRegexPattern }][{ diactiticsKeywordsRegexPattern}0-9{ (OptionInlineNamespacesEvaluationActive ? @"\." : string.Empty) }]*)\s*(?<isgeneric>[<](?>[^<>]+|(?<gentag>[<])|(?<-gentag>[>]))*(?(gentag)(?!))[>])?\s*((?<isfunction>[(])|(?<isArray>\[))?"; } }
55+
private string InstanceCreationWithNewKeywordRegexPattern { get { return $@"^new\s+(?<name>[{ diactiticsKeywordsRegexPattern }][{ diactiticsKeywordsRegexPattern}0-9{ (OptionInlineNamespacesEvaluationActive ? @"\." : string.Empty) }]*)\s*(?<isgeneric>[<](?>[^<>]+|(?<gentag>[<])|(?<-gentag>[>]))*(?(gentag)(?!))[>])?\s*((?<isfunction>[(])|(?<isArray>\[)|(?<isInit>[{{]))?"; } }
5556
private Regex instanceCreationWithNewKeywordRegex = null;
5657
private string CastRegexPattern { get { return $@"^\(\s*(?<typeName>[{ diactiticsKeywordsRegexPattern }][{ diactiticsKeywordsRegexPattern }0-9\{ (OptionInlineNamespacesEvaluationActive ? @"\." : string.Empty) }[\]<>]*[?]?)\s*\)"; } }
5758
private Regex castRegex = null;
@@ -1423,15 +1424,52 @@ private bool EvaluateInstanceCreationWithNewKeyword(string expr, string restOfEx
14231424

14241425
i += instanceCreationMatch.Length;
14251426

1427+
if (type == null)
1428+
throw new ExpressionEvaluatorSyntaxErrorException($"Type or class {completeName}{genericTypes} is unknown");
1429+
14261430
if (instanceCreationMatch.Groups["isfunction"].Success)
14271431
{
14281432
List<string> constructorArgs = GetExpressionsBetweenParenthesesOrOtherImbricableBrackets(expr, ref i, true);
1429-
1430-
if (type == null)
1431-
throw new ExpressionEvaluatorSyntaxErrorException($"Type or class {completeName}{genericTypes} is unknown");
1433+
i++;
14321434

14331435
List<object> cArgs = constructorArgs.ConvertAll(arg => Evaluate(arg));
1434-
stack.Push(Activator.CreateInstance(type, cArgs.ToArray()));
1436+
1437+
object element = Activator.CreateInstance(type, cArgs.ToArray());
1438+
1439+
Match blockBeginningMatch = blockBeginningRegex.Match(expr.Substring(i));
1440+
1441+
if (blockBeginningMatch.Success)
1442+
{
1443+
i += blockBeginningMatch.Length;
1444+
1445+
List<string> initArgs = GetExpressionsBetweenParenthesesOrOtherImbricableBrackets(expr, ref i, true, ",", "{", "}");
1446+
1447+
if (typeof(IEnumerable).IsAssignableFrom(type))
1448+
{
1449+
MethodInfo methodInfo = type.GetMethod("Add", BindingFlags.Public | BindingFlags.Instance);
1450+
1451+
initArgs.ForEach(subExpr => methodInfo.Invoke(element, new object[] { Evaluate(subExpr) }));
1452+
}
1453+
}
1454+
else
1455+
i--;
1456+
1457+
stack.Push(element);
1458+
}
1459+
else if(instanceCreationMatch.Groups["isInit"].Success)
1460+
{
1461+
List<string> initArgs = GetExpressionsBetweenParenthesesOrOtherImbricableBrackets(expr, ref i, true, ",", "{", "}");
1462+
1463+
object element = Activator.CreateInstance(type, new object[0]);
1464+
1465+
if (typeof(IEnumerable).IsAssignableFrom(type))
1466+
{
1467+
MethodInfo methodInfo = type.GetMethod("Add", BindingFlags.Public | BindingFlags.Instance);
1468+
1469+
initArgs.ForEach(subExpr => methodInfo.Invoke(element, new object[] { Evaluate(subExpr) }));
1470+
}
1471+
1472+
stack.Push(element);
14351473
}
14361474
else if(instanceCreationMatch.Groups["isArray"].Success)
14371475
{
@@ -1462,7 +1500,7 @@ private bool EvaluateInstanceCreationWithNewKeyword(string expr, string restOfEx
14621500
stack.Push(array);
14631501
}
14641502
else
1465-
throw new ExpressionEvaluatorSyntaxErrorException($"A new expression requires that type be followed by () or [](Check : {instanceCreationMatch.Value})");
1503+
throw new ExpressionEvaluatorSyntaxErrorException($"A new expression requires that type be followed by (), [] or {{}}(Check : {instanceCreationMatch.Value})");
14661504

14671505
return true;
14681506
}

0 commit comments

Comments
 (0)