Example #1
0
        public void CachedLambdaCompiler_ArgumentChecking()
        {
            var f = (Expression <Action>)(() => Console.WriteLine());
            var l = (LambdaExpression)f;
            var c = VoidCompiledDelegateCache.Instance;
            var h = ConstantHoister.Create(useDefaultForNull: false);

#pragma warning disable IDE0034 // Simplify 'default' expression (illustrative of method signature)
            Assert.ThrowsException <ArgumentNullException>(() => CachedLambdaCompiler.Compile(default(LambdaExpression), c));
            Assert.ThrowsException <ArgumentNullException>(() => CachedLambdaCompiler.Compile(l, cache: null));
            Assert.ThrowsException <ArgumentNullException>(() => CachedLambdaCompiler.Compile(default(Expression <Action>), c));
            Assert.ThrowsException <ArgumentNullException>(() => CachedLambdaCompiler.Compile(f, cache: null));

            Assert.ThrowsException <ArgumentNullException>(() => CachedLambdaCompiler.Compile(default(LambdaExpression), c, outliningEnabled: false));
            Assert.ThrowsException <ArgumentNullException>(() => CachedLambdaCompiler.Compile(l, cache: null, outliningEnabled: false));
            Assert.ThrowsException <ArgumentNullException>(() => CachedLambdaCompiler.Compile(default(Expression <Action>), c, outliningEnabled: false));
            Assert.ThrowsException <ArgumentNullException>(() => CachedLambdaCompiler.Compile(f, cache: null, outliningEnabled: false));

            Assert.ThrowsException <ArgumentNullException>(() => CachedLambdaCompiler.Compile(default(LambdaExpression), c, outliningEnabled: false, h));
            Assert.ThrowsException <ArgumentNullException>(() => CachedLambdaCompiler.Compile(l, cache: null, outliningEnabled: false, h));
            Assert.ThrowsException <ArgumentNullException>(() => CachedLambdaCompiler.Compile(default(Expression <Action>), c, outliningEnabled: false, h));
            Assert.ThrowsException <ArgumentNullException>(() => CachedLambdaCompiler.Compile(f, cache: null, outliningEnabled: false, h));

            Assert.ThrowsException <ArgumentNullException>(() => CachedLambdaCompiler.Compile(l, c, outliningEnabled: false, hoister: null));
            Assert.ThrowsException <ArgumentNullException>(() => CachedLambdaCompiler.Compile(f, c, outliningEnabled: false, hoister: null));
#pragma warning restore IDE0034 // Simplify 'default' expression
        }
Example #2
0
        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());
        }
Example #3
0
        private static IEqualityComparer <Expression> GetExpressionHeapComparer()
        {
            var comparer = default(IEqualityComparer <Expression>);
            var cache    = new ExpressionHeap(ConstantHoister.Create(false), cmp => { comparer = cmp; return(new Cache <Expression>(new CacheStorage <Expression>(cmp))); });

            return(comparer);
        }
Example #4
0
        public void ConstantHoister_TypeSeparation()
        {
            var e   = Expression.Add(Expression.Constant(new Bar()), Expression.Constant(new Foo()));
            var res = ConstantHoister.Hoist(e, useDefaultForNull: false);

            Assert.AreEqual(2, res.Environment.Count);
        }
        public void ExpressionPolicy_PropertyChecks()
        {
            var policy = new ExpressionPolicy();

            Assert.AreSame(DefaultExpressionPolicy.Instance.DelegateCache, policy.DelegateCache);
            Assert.AreSame(DefaultExpressionPolicy.Instance.InMemoryCache, policy.InMemoryCache);
            Assert.AreSame(DefaultExpressionPolicy.Instance.ConstantHoister, policy.ConstantHoister);

            var delegateCache   = new SimpleCompiledDelegateCache();
            var expressionCache = new ExpressionHeap();
            var constantHoister = ConstantHoister.Create(false);

            policy.DelegateCache   = delegateCache;
            policy.InMemoryCache   = expressionCache;
            policy.ConstantHoister = constantHoister;

            Assert.AreSame(delegateCache, policy.DelegateCache);
            Assert.AreSame(expressionCache, policy.InMemoryCache);
            Assert.AreSame(constantHoister, policy.ConstantHoister);

            policy.DelegateCache   = null;
            policy.InMemoryCache   = null;
            policy.ConstantHoister = null;

            Assert.AreSame(DefaultExpressionPolicy.Instance.DelegateCache, policy.DelegateCache);
            Assert.AreSame(DefaultExpressionPolicy.Instance.InMemoryCache, policy.InMemoryCache);
            Assert.AreSame(DefaultExpressionPolicy.Instance.ConstantHoister, policy.ConstantHoister);
        }
Example #6
0
        public void ConstantHoister_Exclusions_Checks()
        {
#pragma warning disable IDE0034 // Simplify 'default' expression (illustrative of method signature)
            AssertEx.ThrowsException <ArgumentException>(() =>
            {
                ConstantHoister.Create(false,
                                       (Expression <Func <int, int> >)(h => h + 1)
                                       );
            }, ex =>
            {
                Assert.AreEqual(typeof(ArgumentException), ex.GetType());
                Assert.IsTrue(ex.Message.Contains("not a method call, new, or member access"));
            });

            AssertEx.ThrowsException <ArgumentException>(() =>
            {
                ConstantHoister.Create(false,
                                       (Expression <Func <string, string> >)(h => string.Format(h, /* convert */ 42))
                                       );
            }, ex =>
            {
                Assert.AreEqual(typeof(ArgumentException), ex.GetType());
                Assert.IsTrue(ex.Message.Contains("not a constant or a default expression"));
            });

            AssertEx.ThrowsException <ArgumentException>(() =>
            {
                ConstantHoister.Create(false,
                                       (Expression <Func <string> >)(() => string.Format("bar", default(object[])))
                                       );
            }, ex =>
            {
                Assert.AreEqual(typeof(ArgumentException), ex.GetType());
                Assert.IsTrue(ex.Message.Contains("no holes for constants"));
            });

            AssertEx.ThrowsException <ArgumentException>(() =>
            {
                ConstantHoister.Create(false,
                                       (Expression <Func <string, string> >)(h => string.Format("bar", default(object[])))
                                       );
            }, ex =>
            {
                Assert.AreEqual(typeof(ArgumentException), ex.GetType());
                Assert.IsTrue(ex.Message.Contains("not used"));
            });

            AssertEx.ThrowsException <ArgumentException>(() =>
            {
                ConstantHoister.Create(false,
                                       (Expression <Func <string, string> >)(h => string.Concat(h, h))
                                       );
            }, ex =>
            {
                Assert.AreEqual(typeof(ArgumentException), ex.GetType());
                Assert.IsTrue(ex.Message.Contains("used multiple times"));
            });
#pragma warning restore IDE0034 // Simplify 'default' expression
        }
Example #7
0
        public void ConstantHoister_Null1()
        {
            var c   = Expression.Constant(value: null, typeof(string));
            var res = ConstantHoister.Hoist(c, useDefaultForNull: false);

            Assert.AreEqual(1, res.Environment.Count);
            var e = res.Environment.Single();

            Assert.AreEqual(c.Type, e.Key.Type);
            Assert.AreEqual(default(string), e.Value);
        }
Example #8
0
        public void ConstantHoister_Null3()
        {
            var c   = Expression.Constant(value: null, typeof(string));
            var res = ConstantHoister.Hoist(c, useDefaultForNull: true);

            Assert.AreEqual(0, res.Environment.Count);
            var e = res.Expression as DefaultExpression;

            Assert.IsNotNull(e);
            Assert.AreEqual(c.Type, e.Type);
        }
Example #9
0
            public Impl(ConstantHoister parent)
            {
                _parent     = parent;
                _constants  = new Dictionary <object, ParameterExpression>(TypeAwareComparer.Instance);
                Environment = new List <Binding>();

                if (!_parent._useDefaultForNull)
                {
                    _nulls = new Dictionary <Type, ParameterExpression>();
                }
            }
Example #10
0
        private static ExpressionWithEnvironment HoistAndEval(ConstantHoister h, Expression e)
        {
            var c = h.Hoist(e);

            var i = c.ToInvocation().Evaluate();

            var r = e.Evaluate();

            Assert.AreEqual(r, i);

            return(c);
        }
Example #11
0
        public void ExpressionHeap_DummyCacheStorage()
        {
            var e1 = Expression.Lambda(Expression.Default(typeof(string)));
            var e2 = Expression.Lambda(Expression.Default(typeof(string)));

            Assert.AreNotSame(e1, e2);

            var heap = new ExpressionHeap(ConstantHoister.Create(false), _ => new Cache <Expression>(new DummyStorage()));
            var r1   = heap.Create(e1);
            var r2   = heap.Create(e2);

            Assert.AreNotSame(r1.Value, r2.Value);
        }
Example #12
0
        private static ExpressionWithEnvironment HoistAndEval(Expression e)
        {
            var c1 = ConstantHoister.Hoist(e, useDefaultForNull: false);
            var c2 = ConstantHoister.Hoist(e, useDefaultForNull: true);

            var i1 = c1.ToInvocation().Evaluate();
            var i2 = c2.ToInvocation().Evaluate();

            var e1 = e.Evaluate();

            Assert.AreEqual(e1, i1);
            Assert.AreEqual(e1, i2);

            return(c1);
        }
Example #13
0
        public void CachedLambdaCompiler_CustomHoister2()
        {
#pragma warning disable IDE0034 // Simplify 'default' expression (illustrative of method signature)
            var h = ConstantHoister.Create(false,
                                           (Expression <Func <string, string> >)(s => string.Format(s, default(object[])))
                                           );
#pragma warning restore IDE0034 // Simplify 'default' expression

            foreach (var outline in new[] { false, true })
            {
                var added = 0;

                var cache = new MyCache();
                cache.Added += () => added++;

                Expression <Func <int, string> > f1 = x => string.Format("{0}:{1}", new object[] { x, 43 });
                Expression <Func <int, string> > f2 = x => string.Format("{0}:{1}", new object[] { x, 44 });
                Expression <Func <int, string> > f3 = x => string.Format("{1}:{0}", new object[] { x, 45 });

                for (var i = 0; i < 2; i++)
                {
                    var d1 = ((LambdaExpression)f1).Compile(cache, outline, h);
                    var r1 = d1.DynamicInvoke(42);

                    Assert.AreEqual("42:43", r1);
                    Assert.AreEqual(1, added);
                }

                for (var i = 0; i < 2; i++)
                {
                    var d2 = ((LambdaExpression)f2).Compile(cache, outline, h);
                    var r2 = d2.DynamicInvoke(42);

                    Assert.AreEqual("42:44", r2);
                    Assert.AreEqual(1, added);
                }

                for (var i = 0; i < 2; i++)
                {
                    var d3 = ((LambdaExpression)f3).Compile(cache, outline, h);
                    var r3 = d3.DynamicInvoke(42);

                    Assert.AreEqual("45:42", r3);
                    Assert.AreEqual(2, added);
                }
            }
        }
Example #14
0
        public void QuotedOfT_WithExpressionPolicy()
        {
            var policy = new TestPolicy
            {
                InMemoryCache   = new ExpressionHeap(),
                DelegateCache   = new SimpleCompiledDelegateCache(),
                ConstantHoister = ConstantHoister.Create(useDefaultForNull: false)
            };

            var expr = Expression.Constant(42, typeof(int));

            var q = new Quoted <int>(expr, policy);

            Assert.AreEqual(42, q.Value);
            Assert.AreNotSame(expr, q.Expression);
            Assert.IsTrue(new ExpressionEqualityComparer().Equals(expr, q.Expression));
        }
Example #15
0
        public void ExpressionHeap_HoistedConstants_Shared()
        {
            var heap = new ExpressionHeap(ConstantHoister.Create(
                                              false,
                                              (Expression <Func <string, string> >)(c => string.Format(c, default(object)))));

            Expression <Func <object, string> > f1 = x => string.Format("{0}", x);
            Expression <Func <object, string> > f2 = x => string.Format("{0}", x);

            Assert.AreNotSame(f1, f2);

            var r1 = heap.Create(f1);
            var r2 = heap.Create(f2);
            var v1 = r1.Value;
            var v2 = r2.Value;

            Assert.AreSame(v1, v2);
        }
Example #16
0
        public void ConstantHoister_Exclusions()
        {
            var hp     = Expression.Parameter(typeof(string));
            var concat = (MethodInfo)ReflectionHelpers.InfoOf(() => string.Concat("a", "b"));

#pragma warning disable IDE0034 // Simplify 'default' expression (illustrative of method signature)
            var hoister = ConstantHoister.Create(false,
                                                 (Expression <Func <string, string> >)(h => string.Format(h, default(object[]))),
                                                 (Expression <Func <string, Regex> >)(h => new Regex(h)),
                                                 (Expression <Func <string, int> >)(h => h.Length),
                                                 (Expression <Func <string, string> >)(h => h.ToUpper()),
                                                 Expression.Lambda <Func <string, string> >(Expression.Call(concat, hp, Expression.Default(typeof(string))), hp),
                                                 Expression.Lambda <Func <string, string> >(Expression.Call(concat, Expression.Default(typeof(string)), hp), hp)
                                                 );
#pragma warning restore IDE0034

            var e1 = (Expression <Func <string> >)(() => string.Format("{0}:{1}", new object[] { 123, "foo" }));
            var e2 = (Expression <Func <bool> >)(() => new Regex("abc").IsMatch("bar"));
            var e3 = (Expression <Func <int> >)(() => "qux".Length);
            var e4 = (Expression <Func <string> >)(() => "baz".ToUpper());
            var e5 = (Expression <Func <string> >)(() => string.Concat("bar", "foo"));

            var r1 = HoistAndEval(hoister, e1.Body);
            var r2 = HoistAndEval(hoister, e2.Body);
            var r3 = HoistAndEval(hoister, e3.Body);
            var r4 = HoistAndEval(hoister, e4.Body);
            var r5 = HoistAndEval(hoister, e5.Body);

            Assert.AreEqual(2, r1.Environment.Count);
            Assert.IsTrue(r1.Environment.Values.OfType <int>().Any(v => v == 123));
            Assert.IsTrue(r1.Environment.Values.OfType <string>().Any(v => v == "foo"));

            Assert.AreEqual(1, r2.Environment.Count);
            Assert.IsTrue(r2.Environment.Values.OfType <string>().Any(v => v == "bar"));

            Assert.AreEqual(0, r3.Environment.Count);

            Assert.AreEqual(0, r4.Environment.Count);

            Assert.AreEqual(0, r5.Environment.Count);
        }
        protected override CheckpointingQueryEngine CreateQueryEngine(System.Uri uri, IReactiveServiceResolver resolver, IScheduler scheduler, IReactiveMetadata metadata, IKeyValueStore keyValueStore, TraceSource traceSource, IReadOnlyDictionary <string, object> contextElements)
        {
            var engine = base.CreateQueryEngine(uri, resolver, scheduler, metadata, keyValueStore, traceSource, contextElements);

#pragma warning disable IDE0034 // Simplify 'default' expression (illustrative of method signature)
#pragma warning disable CA1305  // Specify IFormatProvider (captured in expression tree)
            var constantHoister = ConstantHoister.Create(
                true,
                (Expression <Func <string, string> >)(c => string.Format(c, default(object))),
                (Expression <Func <string, string> >)(c => string.Format(c, default(object), default(object))),
                (Expression <Func <string, string> >)(c => string.Format(c, default(object), default(object), default(object))),
                (Expression <Func <string, string> >)(c => string.Format(c, default(object[]))),
                (Expression <Func <string, string> >)(c => string.Format(default(IFormatProvider), c, default(object[]))),
                (Expression <Func <string, JProperty> >)(c => new JProperty(c, default(object))),
                (Expression <Func <string, JProperty> >)(c => new JProperty(c, default(object[]))));
#pragma warning restore CA1305  // Specify IFormatProvider
#pragma warning restore IDE0034 // Simplify 'default' expression

            engine.Options.ExpressionPolicy.DelegateCache   = new SimpleCompiledDelegateCache();
            engine.Options.ExpressionPolicy.InMemoryCache   = new QueryEvaluatorExpressionHeap(constantHoister);
            engine.Options.ExpressionPolicy.ConstantHoister = constantHoister;

            return(engine);
        }
Example #18
0
 public void ConstantHoister_ArgumentChecking()
 {
     AssertEx.ThrowsException <ArgumentNullException>(() => ConstantHoister.Hoist(expression: null, useDefaultForNull: false), ex => Assert.AreEqual("expression", ex.ParamName));
     AssertEx.ThrowsException <ArgumentNullException>(() => ConstantHoister.Create(useDefaultForNull: false, exclusions: null), ex => Assert.AreEqual("exclusions", ex.ParamName));
     AssertEx.ThrowsException <ArgumentNullException>(() => ConstantHoister.Create(useDefaultForNull: false).Hoist(expression: null), ex => Assert.AreEqual("expression", ex.ParamName));
 }
Example #19
0
 /// <summary>
 /// Initializes the expression heap with a default constant hoister and template cache.
 /// </summary>
 public ExpressionHeap()
     : this(ConstantHoister.Create(useDefaultForNull : false))
 {
 }