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 }
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()); }
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); }
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); }
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 }
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); }
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); }
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>(); } }
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); }
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); }
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); }
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); } } }
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)); }
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); }
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); }
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)); }
/// <summary> /// Initializes the expression heap with a default constant hoister and template cache. /// </summary> public ExpressionHeap() : this(ConstantHoister.Create(useDefaultForNull : false)) { }