From 9ab3033b1cc4b569c565c9dbc6e232679f73943d Mon Sep 17 00:00:00 2001 From: Rafal Gwizdala Date: Thu, 15 Nov 2018 10:41:27 +0100 Subject: [PATCH 1/2] array() and dictionary() calls added --- .../DynamicExpressionTests.cs | 48 ++++++++++++ Src/System.Linq.Dynamic/DynamicLinq.cs | 73 +++++++++++++++++++ 2 files changed, 121 insertions(+) diff --git a/Src/System.Linq.Dynamic.Test/DynamicExpressionTests.cs b/Src/System.Linq.Dynamic.Test/DynamicExpressionTests.cs index 8617299..6491102 100644 --- a/Src/System.Linq.Dynamic.Test/DynamicExpressionTests.cs +++ b/Src/System.Linq.Dynamic.Test/DynamicExpressionTests.cs @@ -42,6 +42,53 @@ public void ParseLambda_DelegateTypeMethodCall_ReturnsEventHandlerLambdaExpressi Assert.AreEqual(typeof(EventHandler), expression.Type); } + [TestMethod] + public void ParseLambda_NewArrayInit() + { + DateTime dt = DateTime.Now; + + var expr = DynamicExpression.ParseLambda( + typeof(Func), + new [] + { + Expression.Parameter(typeof(DateTime), "dt") + }, + null, + "array(dt.Year, dt.Month, 15, \"ala ma kota\", dt.Ticks, dt.Date.Ticks)" + ); + + + Assert.AreEqual(typeof(object[]), expr.ReturnType); + Assert.AreEqual(typeof(Func), expr.Type); + var texpr = (Expression>)expr; + var fun = texpr.Compile(); + var res = fun(dt); + } + + [TestMethod] + public void ParseLambda_NewDictionary() + { + //this does not work - didnt figure oout how to make useful lambda with dictionary initialization + DateTime dt = DateTime.Now; + + var expr = DynamicExpression.ParseLambda( + typeof(Func>), + new[] + { + Expression.Parameter(typeof(DateTime), "dt") + }, + typeof(Dictionary), + "dictionary(dt.Year as y, dt.Month as m, 15 as fifteen, \"ala ma kota\" as text, dt.Ticks, dt.Date.Ticks as rounded_ticks)" + ); + + + Assert.AreEqual(typeof(Dictionary), expr.ReturnType); + Assert.AreEqual(typeof(Func>), expr.Type); + var texpr = (Expression>>)expr; + var fun = texpr.Compile(); + var res = fun(dt); + } + [TestMethod] public void ParseLambda_VoidMethodCall_ReturnsActionDelegate() { @@ -53,6 +100,7 @@ public void ParseLambda_VoidMethodCall_ReturnsActionDelegate() Assert.AreEqual(typeof(Action), expression.Type); } + [TestMethod] public void CreateClass_TheadSafe() { diff --git a/Src/System.Linq.Dynamic/DynamicLinq.cs b/Src/System.Linq.Dynamic/DynamicLinq.cs index 8a87987..f4a353a 100644 --- a/Src/System.Linq.Dynamic/DynamicLinq.cs +++ b/Src/System.Linq.Dynamic/DynamicLinq.cs @@ -790,6 +790,8 @@ interface IEnumerableSignatures static readonly string keywordIt = "it"; static readonly string keywordIif = "iif"; static readonly string keywordNew = "new"; + static readonly string keywordArray = "array"; + static readonly string keywordDic = "dictionary"; static readonly string keywordOuterIt = "outerIt"; static Dictionary keywords; @@ -1262,6 +1264,8 @@ Expression ParseIdentifier() if (value == (object)keywordOuterIt) return ParseOuterIt(); if (value == (object)keywordIif) return ParseIif(); if (value == (object)keywordNew) return ParseNew(); + if (value == (object)keywordArray) return ParseNewArray(); + if (value == (object)keywordDic) return ParseNewDictionary(); NextToken(); return (Expression)value; } @@ -1377,6 +1381,73 @@ Expression ParseNew() return Expression.MemberInit(Expression.New(type), bindings); } + /// + /// array(x1, x2, x3, ....) + /// + /// + Expression ParseNewArray() + { + NextToken(); + ValidateToken(TokenId.OpenParen, Res.OpenParenExpected); + NextToken(); + List expressions = new List(); + while (true) + { + int exprPos = token.pos; + Expression expr = ParseExpression(); + expr = Expression.Convert(expr, typeof(object)); + expressions.Add(expr); + if (token.id != TokenId.Comma) break; + NextToken(); + } + ValidateToken(TokenId.CloseParen, Res.CloseParenOrCommaExpected); + NextToken(); + return Expression.NewArrayInit(typeof(object), expressions); + } + + //dictionary string->object + Expression ParseNewDictionary() + { + + NextToken(); + ValidateToken(TokenId.OpenParen, Res.OpenParenExpected); + NextToken(); + + List elemz = new List(); + var dicType = typeof(Dictionary); + var mi = dicType.GetMethod("Add"); + + while (true) + { + int exprPos = token.pos; + Expression expr = ParseExpression(); + string propName; + if (TokenIdentifierIs("as")) + { + NextToken(); + propName = GetIdentifier(); + NextToken(); + } + else + { + MemberExpression me = expr as MemberExpression; + if (me == null) throw ParseError(exprPos, Res.MissingAsClause); + propName = me.Member.Name; + } + if (expr.Type != typeof(object)) expr = Expression.Convert(expr, typeof(object)); + + var el = Expression.ElementInit(mi, Expression.Constant(propName), expr); + elemz.Add(el); + if (token.id != TokenId.Comma) break; + NextToken(); + } + ValidateToken(TokenId.CloseParen, Res.CloseParenOrCommaExpected); + NextToken(); + + return Expression.ListInit(Expression.New(dicType), elemz); + + } + Expression ParseLambdaInvocation(LambdaExpression lambda) { int errorPos = token.pos; @@ -2436,6 +2507,8 @@ static Dictionary CreateKeywords() d.Add(keywordOuterIt, keywordOuterIt); d.Add(keywordIif, keywordIif); d.Add(keywordNew, keywordNew); + d.Add(keywordArray, keywordArray); + d.Add(keywordDic, keywordDic); foreach (Type type in predefinedTypes) d.Add(type.Name, type); return d; } From 8465ed5c8fc41e573fb3546df2817f6f5be482a5 Mon Sep 17 00:00:00 2001 From: Rafal Gwizdala Date: Fri, 16 Nov 2018 21:54:32 +0100 Subject: [PATCH 2/2] rgdev package version - temporary nuget --- NuGet/rgdev_System.Linq.Dynamic.1.0.8.nuspec | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 NuGet/rgdev_System.Linq.Dynamic.1.0.8.nuspec diff --git a/NuGet/rgdev_System.Linq.Dynamic.1.0.8.nuspec b/NuGet/rgdev_System.Linq.Dynamic.1.0.8.nuspec new file mode 100644 index 0000000..3e007d5 --- /dev/null +++ b/NuGet/rgdev_System.Linq.Dynamic.1.0.8.nuspec @@ -0,0 +1,20 @@ + + + + rgdev_System.Linq.Dynamic + 1.0.8 + Microsoft + Microsoft + false + http://www.opensource.org/licenses/ms-pl + https://github.com/kahanu/System.Linq.Dynamic + This is the Microsoft assembly for the .Net 4.0 Dynamic language functionality. + lafar6502/System.Linq.Dynamic build +contains some modifications not merged yet into the original repo kahanu + system linq dynamic + + + + + + \ No newline at end of file