public void ConstantHoister_ManOrBoy() { #pragma warning disable IDE0079 // The following supression is flagged as unnecessary on .NET Framework (but is required for other targets) #pragma warning disable CA1845 // Use span-based 'string.Concat' and 'AsSpan' instead of 'Substring' var e = (Expression <Func <IEnumerable <int>, IEnumerable <string> > >)(xs => from x in xs let y = x + 1 where y > 0 let s = x.ToString() where !s.EndsWith("Foo") select s.Substring(0, 1) + "Foo"); #pragma warning restore CA1847 #pragma warning restore IDE0079 var c = ConstantHoister.Hoist(e, useDefaultForNull: false); Assert.AreEqual(3, c.Environment.Count); Assert.IsTrue(c.Environment.Values.Contains(0)); Assert.IsTrue(c.Environment.Values.Contains(1)); Assert.IsTrue(c.Environment.Values.Contains("Foo")); var i = (Expression)c.ToInvocation(); Assert.AreEqual("((Func<int, int, string, Func<IEnumerable<int>, IEnumerable<string>>>)((int @p0, int @p1, string @p2) => (IEnumerable<int> xs) => xs.Select((int x) => new { x, y = x + @p0 }).Where(t => t.y > @p1).Select(t => new { t, s = t.x.ToString() }).Where(t => !t.s.EndsWith(@p2)).Select(t => t.s.Substring(@p1, @p0) + @p2)))(1, 0, \"Foo\")", i.ToCSharpString()); Assert.AreEqual("int @p0 = 1;\r\nint @p1 = 0;\r\nstring @p2 = \"Foo\";\r\nreturn (IEnumerable<int> xs) => xs.Select((int x) => new { x, y = x + @p0 }).Where(t => t.y > @p1).Select(t => new { t, s = t.x.ToString() }).Where(t => !t.s.EndsWith(@p2)).Select(t => t.s.Substring(@p1, @p0) + @p2);\r\n", c.ToCSharpString()); var t = c.ToString(); var u = Regex.Replace(t, @"\<\>f__AnonymousType[\da-fA-F]*", "anon"); var v = Regex.Replace(u, @"\<\>h__TransparentIdentifier[\da-fA-F]*", "tran"); Assert.AreEqual("(xs => xs.Select(x => new anon`2(x = x, y = (x + @p0))).Where(tran => (tran.y > @p1)).Select(tran => new anon`2(tran = tran, s = tran.x.ToString())).Where(tran => Not(tran.s.EndsWith(@p2))).Select(tran => (tran.s.Substring(@p1, @p0) + @p2)))[|@p0 : System.Int32 = 1, @p1 : System.Int32 = 0, @p2 : System.String = \"Foo\"|]", v); i = AnonymousTypeTupletizer.Tupletize(i, Expression.Constant(value: null)); i = CompilerGeneratedNameEliminator.Prettify(i); var f = i.Evaluate <Func <IEnumerable <int>, IEnumerable <string> > >(); var g = f(new[] { 123, 234, 987, 876 }); Assert.IsTrue(new[] { "1Foo", "2Foo", "9Foo", "8Foo" }.SequenceEqual(g)); Assert.AreEqual(@"Invoke((@p0, @p1, @p2) => xs => xs.Select(x => new Tuple`2(x, (x + @p0))).Where(t => (t.Item2 > @p1)).Select(t => new Tuple`2(t, t.Item1.ToString())).Where(t => Not(t.Item2.EndsWith(@p2))).Select(t => (t.Item2.Substring(@p1, @p0) + @p2)), 1, 0, ""Foo"")", i.ToString()); }
public void CompilerGeneratedNameEliminator_Simple5() { var p = Expression.Parameter(typeof(int), "x"); var q = CompilerGeneratedNameEliminator.Prettify(p); Assert.AreSame(p, q); }
public void CompilerGeneratedNameEliminator_Simple4() { var p = (from x in new[] { 1, 2, 3 }.AsQueryable() where x > 0 select x *x).Expression; var q = CompilerGeneratedNameEliminator.Prettify(p); Assert.AreSame(p, q); }
public void CompilerGeneratedNameEliminator_Simple1() { var q = (from x in new[] { 1, 2, 3 }.AsQueryable() let y = x + 1 let z = x + y select x * y + z).Expression; var p = CompilerGeneratedNameEliminator.Prettify(q); new CheckVariableNames().Visit(p); }
public void CompilerGeneratedNameEliminator_Simple6() { var p = Expression.Parameter(typeof(int), "<>h__TransparentIdentifier123"); var q = CompilerGeneratedNameEliminator.Prettify(p); Assert.AreEqual(p.Type, q.Type); Assert.AreEqual("t", ((ParameterExpression)q).Name); }
public void CompilerGeneratedNameEliminator_Simple7() { var x = Expression.Parameter(typeof(int), "<>h__TransparentIdentifier1"); var y = Expression.Parameter(typeof(int), "<>h__TransparentIdentifier2"); var p = Expression.Lambda <Func <int, Func <int, int> > >(Expression.Lambda <Func <int, int> >(x, y), x); var q = (Expression <Func <int, Func <int, int> > >)CompilerGeneratedNameEliminator.Prettify(p); Assert.AreEqual("t => t0 => t", q.ToString()); Assert.AreEqual(2, p.Compile()(2)(3)); Assert.AreEqual(2, q.Compile()(2)(3)); }
public void CompilerGeneratedNameEliminator_Simple2() { #pragma warning disable IDE0079 // Remove unnecessary suppression. #pragma warning disable CA1806 // Use of Any() claimed to be discarded. Seems like an analyzer bug but failing to repro in isolation. var q = (from x in new[] { 1, 2, 3 }.AsQueryable() let y = x + 1 where (from z in new[] { 4, 5 } let a = z + y select z).Any(b => b > 0) select x *y).Expression; var p = CompilerGeneratedNameEliminator.Prettify(q); new CheckVariableNames().Visit(p); #pragma warning restore CA1806 #pragma warning restore IDE0079 }
public void AnonymousTypeTupletizer_ManOrBoy() { var expr = (from x in Enumerable.Empty <object>().AsQueryable() group x by x into g let a = g.OfType <bool>() let b = g.OfType <string>() let z = Enumerable.Zip(a, b, (x, y) => new { x, y }) from t in z select t.x ? t.y : "null") .Expression; var res = AnonymousTypeTupletizer.Tupletize(expr, Expression.Constant(value: null)); var csharp = CompilerGeneratedNameEliminator.Prettify(res).ToCSharpString(); Assert.AreEqual( StripWhitespace(@" __c0.GroupBy<object, object>((object x) => x) .Select<IGrouping<object, object>, Tuple<IGrouping<object, object>, IEnumerable<bool>>>( (IGrouping<object, object> g) => new Tuple<IGrouping<object, object>, IEnumerable<bool>>( g, g.OfType<bool>())) .Select<Tuple<IGrouping<object, object>, IEnumerable<bool>>, Tuple<Tuple<IGrouping<object, object>, IEnumerable<bool>>, IEnumerable<string>>>( (Tuple<IGrouping<object, object>, IEnumerable<bool>> t) => new Tuple<Tuple<IGrouping<object, object>, IEnumerable<bool>>, IEnumerable<string>>( t, t.Item1.OfType<string>())) .Select<Tuple<Tuple<IGrouping<object, object>, IEnumerable<bool>>, IEnumerable<string>>, Tuple<Tuple<Tuple<IGrouping<object, object>, IEnumerable<bool>>, IEnumerable<string>>, IEnumerable<Tuple<bool, string>>>>( (Tuple<Tuple<IGrouping<object, object>, IEnumerable<bool>>, IEnumerable<string>> t) => new Tuple<Tuple<Tuple<IGrouping<object, object>, IEnumerable<bool>>, IEnumerable<string>>, IEnumerable<Tuple<bool, string>>>( t, t.Item1.Item2.Zip<bool, string, Tuple<bool, string>>( t.Item2, (bool x, string y) => new Tuple<bool, string>(x, y)))) .SelectMany<Tuple<Tuple<Tuple<IGrouping<object, object>, IEnumerable<bool>>, IEnumerable<string>>, IEnumerable<Tuple<bool, string>>>, Tuple<bool, string>, string>( (Tuple<Tuple<Tuple<IGrouping<object, object>, IEnumerable<bool>>, IEnumerable<string>>, IEnumerable<Tuple<bool, string>>> t) => t.Item2, (Tuple<Tuple<Tuple<IGrouping<object, object>, IEnumerable<bool>>, IEnumerable<string>>, IEnumerable<Tuple<bool, string>>> t, Tuple<bool, string> t0) => t0.Item1 ? t0.Item2 : ""null"")"), StripWhitespace(csharp) );
public void ExpressionSlimEntityTypeRecordizer_Constants_ManOrBoy2() { Expression <Func <IEnumerable <A>, IEnumerable <int> > > f = xs => from x in xs let b = x.B from c in b.Cs let d = c.D where d > 0 let e = new A { B = new B { Cs = new C[] { c, new C { D = d + 1, Es = new List <E> { new E { F = d * d } } } } } } let z = new A { B = { Cs = new C[] { c, new C { D = d + 1, Es ={ new E { F = d * d } } } } } } where e.B.Cs[1].Es[0].F == z.B.Cs[1].Es[0].F select 7 * e.B.Cs.Sum(y => y.D); var g = f.Compile(); var res = g(new[] { new A { B = new B { Cs = new C[] { new C { D = 23 } } } }, new A { B = new B { Cs = new C[] { new C { D = -1 } } } }, new A { B = new B { Cs = new C[] { new C { D = 87 } } } }, }); var eta = new ExpressionSlimEntityTypeRecordizer(); var converter = new ExpressionToExpressionSlimConverter(new DataModelTypeSpace()); var slim = converter.Visit(f); var h = (LambdaExpression)eta.Apply(slim).ToExpression(); var anonA = h.Parameters[0].Type.GetGenericArguments()[0]; var propB = anonA.GetProperty("b"); var anonB = propB.PropertyType; var propCs = anonB.GetProperty("cs"); var anonC = propCs.PropertyType.GetElementType(); var propD = anonC.GetProperty("d"); var c23 = Activator.CreateInstance(anonC); propD.SetValue(c23, 23); var cm1 = Activator.CreateInstance(anonC); propD.SetValue(cm1, -1); var c87 = Activator.CreateInstance(anonC); propD.SetValue(c87, 87); var cs23 = (IList)Array.CreateInstance(anonC, 1); cs23[0] = c23; var csm1 = (IList)Array.CreateInstance(anonC, 1); csm1[0] = cm1; var cs87 = (IList)Array.CreateInstance(anonC, 1); cs87[0] = c87; var b23 = Activator.CreateInstance(anonB); propCs.SetValue(b23, cs23); var bm1 = Activator.CreateInstance(anonB); propCs.SetValue(bm1, csm1); var b87 = Activator.CreateInstance(anonB); propCs.SetValue(b87, cs87); var a23 = Activator.CreateInstance(anonA); propB.SetValue(a23, b23); var am1 = Activator.CreateInstance(anonA); propB.SetValue(am1, bm1); var a87 = Activator.CreateInstance(anonA); propB.SetValue(a87, b87); var inp = (IList)Array.CreateInstance(anonA, 3); inp[0] = a23; inp[1] = am1; inp[2] = a87; var p = CompilerGeneratedNameEliminator.Prettify(h).ToCSharpString(allowCompilerGeneratedNames: true).Replace("<>a__RecordType", "rec").Replace("<>h__TransparentIdentifier", "__t"); Assert.IsTrue(true, p); var output = (IEnumerable <int>)h.Compile().DynamicInvoke(new object[] { inp }); Assert.IsTrue(res.SequenceEqual(output)); }
public void CompilerGeneratedNameEliminator_ArgumentChecking() { AssertEx.ThrowsException <ArgumentNullException>(() => CompilerGeneratedNameEliminator.Prettify(expression: null), ex => Assert.AreEqual("expression", ex.ParamName)); }