/// <summary>
        /// A utility method to find and organize all the unbound parameters with Reactive entity types.
        /// </summary>
        /// <param name="expression">The expression to search for Reactive entities.</param>
        /// <returns>The Reactive entities in the expression, organized by entity type.</returns>
        public static ReactiveEntities Find(ExpressionSlim expression)
        {
            var impl = new Impl();

            impl.Visit(expression);
            return(impl.Entities);
        }
示例#2
0
        /// <summary>
        /// Finds all the free variables in an expression.
        /// </summary>
        /// <param name="expression">The expression to visit.</param>
        /// <returns>The set of free variables.</returns>
        public static HashSet <ParameterExpressionSlim> Find(ExpressionSlim expression)
        {
            var impl = new Impl();

            impl.Visit(expression);
            return(impl.Globals);
        }
        /// <summary>
        /// Serializes an expression to Bonsai.
        /// </summary>
        /// <param name="expression">Expression to serialize.</param>
        /// <returns>Bonsai representation of the given expression.</returns>
        public Json.Expression Serialize(ExpressionSlim expression)
        {
            if (_mergeContext && _serializationState != null)
            {
                return(new SerializerImpl(_serializationState, _liftFactory).Visit(expression));
            }
            else
            {
                var state = new SerializationState(_version);

                _serializationState = state;

                var body    = new SerializerImpl(state, _liftFactory).Visit(expression);
                var context = state.ToJson();

                _serializationState = null;

                // PERF: We could consider creating a specialized IDictionary for the
                //       top-level JSON structure to avoid Dictionary allocation.

                return(Json.Expression.Object(new Dictionary <string, Json.Expression>(2)
                {
                    { "Context", context },
                    { "Expression", body },
                }));
            }
        }
        /// <summary>
        /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression.
        /// </summary>
        /// <param name="target">The <see cref="Target" /> property of the result.</param>
        /// <param name="defaultValue">The <see cref="DefaultValue" /> property of the result.</param>
        /// <returns>This expression if no children changed, or an expression with the updated children.</returns>
        public LabelExpressionSlim Update(LabelTargetSlim target, ExpressionSlim defaultValue)
        {
            if (target == Target && defaultValue == DefaultValue)
            {
                return(this);
            }

            return(new LabelExpressionSlim(target, defaultValue));
        }
        /// <summary>
        /// Method to reduce a slim expression to an expression.
        /// </summary>
        /// <param name="expression">The slim expression.</param>
        /// <returns>The expression represented by the slim expression.</returns>
        public virtual Expression Reduce(ExpressionSlim expression)
        {
            if (expression == null)
            {
                return(null);
            }

            return(expression.ToExpression()); // NB: Derived class can override to specify a factory.
        }
示例#6
0
        private static void Unpack(LambdaExpression expression, out Expression body, out IEnumerable <ParameterExpression> parameters)
        {
            var slimLambda = expression != null ? (LambdaExpressionSlim)expression.ToExpressionSlim() : null;

            ExpressionSlimTupletizer.Unpack(slimLambda, out var slimBody, out var slimParameters);
            var fatLambda = (LambdaExpression)ExpressionSlim.Lambda(slimBody, slimParameters).ToExpression();

            body       = fatLambda.Body;
            parameters = fatLambda.Parameters;
        }
示例#7
0
        private static TypeSlim Derive(ExpressionSlim expression)
        {
            var result = s_derivationVisitor.Visit(expression);

            if (result == null)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Could not derive type of '{0}' for use as component in tuple.", expression));
            }
            return(result);
        }
示例#8
0
        public void FreeVariableScannerSlim_Find_CatchBlock1()
        {
            var p1 = ExpressionSlim.Parameter(SlimType, "p1");

            var slimExpr = ExpressionSlim.TryCatch(ExpressionSlim.Empty(), ExpressionSlim.Catch(SlimType, p1));

            var free = FreeVariableScannerSlim.Find(slimExpr);

            Assert.AreEqual(1, free.Count);
            Assert.IsTrue(free.Contains(p1));
        }
示例#9
0
        public void FreeVariableScannerSlim_Find_Lambda1()
        {
            var p1 = ExpressionSlim.Parameter(SlimType, "p1");

            var slimExpr = ExpressionSlim.Lambda(p1);

            var free = FreeVariableScannerSlim.Find(slimExpr);

            Assert.AreEqual(1, free.Count);
            Assert.IsTrue(free.Contains(p1));
        }
示例#10
0
        public void UnifyingSerializationHelpers_FindAndUnify_Subscription()
        {
            var metadata = new MetadataMock();
            var uri      = new Uri("test://id");

            metadata.Subscriptions.Add(uri, new MockSubscription(uri));

            var parameter = ExpressionSlim.Parameter(typeof(IAsyncReactiveQubscription).ToTypeSlim(), uri.ToCanonicalString());
            var mappings  = UnifyingSerializationHelpers.FindAndUnify(parameter, metadata);

            Assert.AreEqual(0, mappings.Count());
        }
示例#11
0
        public void UnifyingSerializationHelpers_FindAndUnify_Parameterized()
        {
            var metadata = new MetadataMock();
            var uri      = new Uri("test://id");

            metadata.Observables.Add(uri, new MockParameterizedObservable <int, int>(uri));

            var parameter = ExpressionSlim.Parameter(typeof(Func <int, IAsyncReactiveQbservable <int> >).ToTypeSlim(), uri.ToCanonicalString());
            var mappings  = UnifyingSerializationHelpers.FindAndUnify(parameter, metadata);

            Assert.AreEqual(0, mappings.Count());
        }
        public void ExpressionSlimExtensions_ToExpressionSlim_Null()
        {
#pragma warning disable IDE0034 // Simplify 'default' expression (illustrative of method signature)
            AssertEx.ThrowsException <ArgumentNullException>(() => ((Expression)null).ToExpressionSlim(), ex => Assert.AreEqual("expression", ex.ParamName));
            AssertEx.ThrowsException <ArgumentNullException>(() => ((Expression)null).ToExpressionSlim(ExpressionSlimFactory.Instance), ex => Assert.AreEqual("expression", ex.ParamName));
            AssertEx.ThrowsException <ArgumentNullException>(() => Expression.Constant(1).ToExpressionSlim(default(IExpressionSlimFactory)), ex => Assert.AreEqual("factory", ex.ParamName));

            AssertEx.ThrowsException <ArgumentNullException>(() => ((ExpressionSlim)null).ToExpression(), ex => Assert.AreEqual("expression", ex.ParamName));
            AssertEx.ThrowsException <ArgumentNullException>(() => ((ExpressionSlim)null).ToExpression(ExpressionFactory.Instance), ex => Assert.AreEqual("expression", ex.ParamName));
            AssertEx.ThrowsException <ArgumentNullException>(() => ExpressionSlim.Default(typeof(int).ToTypeSlim()).ToExpression(default(IExpressionFactory)), ex => Assert.AreEqual("factory", ex.ParamName));
#pragma warning restore IDE0034 // Simplify 'default' expression
        }
示例#13
0
        public void ConstantExpressionSlim_ArgumentChecks()
        {
            var t = typeof(string).ToTypeSlim();
            var v = ObjectSlim.Create(value: null, t, typeof(string));

            AssertEx.ThrowsException <ArgumentNullException>(() => ExpressionSlim.Constant(value: null, t), ex => Assert.AreEqual("value", ex.ParamName));
            AssertEx.ThrowsException <ArgumentNullException>(() => ExpressionSlim.Constant(v, type: null), ex => Assert.AreEqual("type", ex.ParamName));

            AssertEx.ThrowsException <ArgumentNullException>(() => new ConstantExpressionSlim(value: null), ex => Assert.AreEqual("value", ex.ParamName));
            AssertEx.ThrowsException <ArgumentNullException>(() => new TypedConstantExpressionSlim(value: null, t), ex => Assert.AreEqual("value", ex.ParamName));
            AssertEx.ThrowsException <ArgumentNullException>(() => new TypedConstantExpressionSlim(v, type: null), ex => Assert.AreEqual("type", ex.ParamName));
        }
示例#14
0
        public void FreeVariableScannerSlim_Find_Block2()
        {
            var p1 = ExpressionSlim.Parameter(SlimType, "p1");
            var p2 = ExpressionSlim.Parameter(SlimType, "p2");

            var slimExpr = ExpressionSlim.Block(new[] { p1 }, ExpressionSlim.Add(p1, p2));

            var free = FreeVariableScannerSlim.Find(slimExpr);

            Assert.AreEqual(1, free.Count);
            Assert.IsTrue(free.Contains(p2));
        }
示例#15
0
        public void UnifyingSerializationHelpers_FindAndUnify_MismatchProperty()
        {
            var metadata = new MetadataMock();
            var uri      = new Uri("test://id");

            metadata.Observables.Add(uri, new MockObservable <TypeWithEnum>(uri));

            var structuralType = StructuralTypeSlimReference.Create(hasValueEqualitySemantics: true, StructuralTypeSlimKind.Record);

            structuralType.AddProperty(structuralType.GetProperty("eg://enum", typeof(int).ToTypeSlim(), EmptyReadOnlyCollection <TypeSlim> .Instance, canWrite: true));
            var observerableType = TypeSlim.Generic(((GenericDefinitionTypeSlim)typeof(IAsyncReactiveQbservable <>).ToTypeSlim()), new TypeSlim[] { structuralType }.ToReadOnly());
            var parameter        = ExpressionSlim.Parameter(observerableType, uri.ToCanonicalString());

            Assert.ThrowsException <InvalidOperationException>(() => UnifyingSerializationHelpers.FindAndUnify(parameter, metadata));
        }
        /// <summary>
        /// Serializes an expression to Bonsai.
        /// </summary>
        /// <param name="expression">Expression to serialize.</param>
        /// <returns>Bonsai representation of the given expression.</returns>
        private Json.Expression JsonSerialize(ExpressionSlim expression)
        {
            var serializationState = new SerializationState(_version);
            var body    = new SerializerImpl(serializationState, GetConstantSerializerDelegate).Visit(expression);
            var context = serializationState.ToJson();

            // PERF: We could consider creating a specialized IDictionary for the
            //       top-level JSON structure to avoid Dictionary allocation.

            return(Json.Expression.Object(new Dictionary <string, Json.Expression>(2)
            {
                { "Context", context },
                { "Expression", body },
            }));
        }
示例#17
0
        public void ExpressionSlimToExpressionConverter_Throw()
        {
            var ex = new Exception();

            var conv = new ExpressionSlimToExpressionConverter();

            {
                var t = ExpressionSlim.Throw(Expression.Constant(ex).ToExpressionSlim());
                var e = conv.Visit(t);

                Assert.AreEqual(ExpressionType.Throw, e.NodeType);

                var u = (UnaryExpression)e;
                Assert.AreEqual(typeof(void), u.Type);

                Assert.AreEqual(ExpressionType.Constant, u.Operand.NodeType);
                var c = (ConstantExpression)u.Operand;
                Assert.AreSame(ex, c.Value);
            }

            {
                var t = ExpressionSlim.Throw(Expression.Constant(ex).ToExpressionSlim(), typeof(int).ToTypeSlim());
                var e = conv.Visit(t);

                Assert.AreEqual(ExpressionType.Throw, e.NodeType);

                var u = (UnaryExpression)e;
                Assert.AreEqual(typeof(int), u.Type);

                Assert.AreEqual(ExpressionType.Constant, u.Operand.NodeType);
                var c = (ConstantExpression)u.Operand;
                Assert.AreSame(ex, c.Value);
            }

            {
                var t = ExpressionSlim.MakeUnary(ExpressionType.Throw, Expression.Constant(ex).ToExpressionSlim(), type: null);
                var e = conv.Visit(t);

                Assert.AreEqual(ExpressionType.Throw, e.NodeType);

                var u = (UnaryExpression)e;
                Assert.AreEqual(typeof(void), u.Type);

                Assert.AreEqual(ExpressionType.Constant, u.Operand.NodeType);
                var c = (ConstantExpression)u.Operand;
                Assert.AreSame(ex, c.Value);
            }
        }
示例#18
0
        public void ExpressionSlimToExpressionConverter_Constant_Null()
        {
            var objNull = ObjectSlim.Create(value: null, typeof(object).ToTypeSlim(), typeof(object));
            var strNull = ObjectSlim.Create(value: null, typeof(string).ToTypeSlim(), typeof(string));

            var n1 = ExpressionSlim.Constant(objNull);
            var n2 = ExpressionSlim.Constant(strNull, typeof(string).ToTypeSlim());

            var c1 = (ConstantExpression)n1.ToExpression();
            var c2 = (ConstantExpression)n2.ToExpression();

            Assert.IsNull(c1.Value);
            Assert.AreEqual(typeof(object), c1.Type);

            Assert.IsNull(c2.Value);
            Assert.AreEqual(typeof(string), c2.Type);
        }
示例#19
0
            /// <summary>
            /// Reduces a slim expression to a Linq expression, first mapping slim
            /// types to types from the expanded definition of the free variables in
            /// the expression.
            /// </summary>
            /// <param name="expression">The expression to reduce.</param>
            /// <returns>The reduced expression.</returns>
            public override Expression Reduce(ExpressionSlim expression)
            {
                EnsureInvertedTypeSpace();

                var freeVariables = FreeVariableScannerSlim.Find(expression);

                foreach (var free in freeVariables)
                {
                    var unifications = FindAndUnify(free, _parent._metadata);

                    foreach (var unification in unifications)
                    {
                        _invertedTypeSpace.MapType(unification.Key, unification.Value);
                    }
                }

                return(base.Reduce(expression));
            }
示例#20
0
        public static TypeSlim GetTypeSlim(this ExpressionSlim e)
        {
            var t = new TypeSlimDerivationVisitor().Visit(e);

            return(t);
        }
        /// <summary>
        /// Method to serialize a slim representation of an expression.
        /// </summary>
        /// <param name="expression">The slim expression to serialize.</param>
        /// <returns>A string representing the expression.</returns>
        public virtual string Serialize(ExpressionSlim expression)
        {
            // PERF: Consider passing in a pooled string builder instance.

            return(JsonSerialize(expression).ToString());
        }
示例#22
0
 /// <summary>
 /// Method to reduce a slim expression to an expression.
 /// </summary>
 /// <param name="expression">A slim expression.</param>
 /// <returns>The expression represented by the slim expression.</returns>
 public override Expression Reduce(ExpressionSlim expression)
 {
     return(Reducer.Visit(expression));
 }
示例#23
0
        public override string Serialize(ExpressionSlim expression)
        {
            var substituted = new ExpressionSlimEntityTypeRecordizer().Apply(expression);

            return(base.Serialize(substituted));
        }
示例#24
0
 private static void AssertToString(ExpressionSlim e, string s)
 {
     Assert.AreEqual(s, e.ToString());
 }
示例#25
0
        public void ExpressionSlim_Update_Tests()
        {
            var boolSlim = new TypeToTypeSlimConverter().Visit(typeof(bool));
            var intExpr1 = ExpressionSlim.Parameter(SlimType);
            var intExpr2 = ExpressionSlim.Parameter(SlimType);
            var intExpr3 = ExpressionSlim.Parameter(SlimType);
            var boolExpr1 = ExpressionSlim.Parameter(boolSlim);
            var boolExpr2 = ExpressionSlim.Parameter(boolSlim);
            var prop = SlimType.GetProperty("Foo", propertyType: null, EmptyReadOnlyCollection <TypeSlim> .Instance, canWrite: true);
            var elementInits = new ElementInitSlim[] { new ElementInitSlim(addMethod: null, arguments: null) }.ToReadOnly();
            var method = SlimType.GetSimpleMethod("Foo", EmptyReadOnlyCollection <TypeSlim> .Instance, returnType: null);

            var b = ExpressionSlim.Add(intExpr1, intExpr2);

            Assert.AreNotSame(b, b.Update(intExpr1, conversion: null, intExpr3));
            Assert.AreNotSame(b, b.Update(intExpr3, conversion: null, intExpr2));

            var c = ExpressionSlim.Condition(boolExpr1, intExpr1, intExpr2);

            Assert.AreNotSame(c, c.Update(boolExpr2, intExpr1, intExpr2));
            Assert.AreNotSame(c, c.Update(boolExpr1, intExpr2, intExpr3));
            Assert.AreNotSame(c, c.Update(boolExpr1, intExpr1, intExpr3));

            var i = ExpressionSlim.MakeIndex(intExpr1, prop, new ExpressionSlim[] { intExpr2 }.ToReadOnly());

            Assert.AreNotSame(i, i.Update(intExpr2, new ExpressionSlim[] { intExpr2 }.ToReadOnly()));
            Assert.AreNotSame(i, i.Update(intExpr1, new ExpressionSlim[] { intExpr3 }.ToReadOnly()));

            var inv = ExpressionSlim.Invoke(intExpr1, new[] { intExpr2 });

            Assert.AreNotSame(inv, inv.Update(intExpr2, new ExpressionSlim[] { intExpr2 }.ToReadOnly()));
            Assert.AreNotSame(inv, inv.Update(intExpr1, new ExpressionSlim[] { intExpr3 }.ToReadOnly()));

            var l = ExpressionSlim.Lambda(intExpr1);

            Assert.AreNotSame(l, l.Update(intExpr2, EmptyReadOnlyCollection <ParameterExpressionSlim> .Instance));
            Assert.AreNotSame(l, l.Update(intExpr1, new ParameterExpressionSlim[] { ExpressionSlim.Parameter(SlimType) }.ToReadOnly()));

            var li = ExpressionSlim.ListInit(ExpressionSlim.New(SlimType));

            Assert.AreNotSame(li, li.Update(ExpressionSlim.New(boolSlim), elementInits));
            Assert.AreNotSame(li, li.Update(ExpressionSlim.New(SlimType), elementInits));

            var ma = ExpressionSlim.Bind(prop, intExpr1);

            Assert.AreNotSame(ma, ma.Update(intExpr2));

            var macc = ExpressionSlim.MakeMemberAccess(instance: null, prop);

            Assert.AreNotSame(macc, macc.Update(intExpr1));

            var ml = ExpressionSlim.ListBind(prop);

            Assert.AreNotSame(ml, ml.Update(elementInits));

            var mm = ExpressionSlim.MemberBind(prop);

            Assert.AreNotSame(mm, mm.Update(new MemberBindingSlim[] { ExpressionSlim.Bind(prop, intExpr1) }.ToReadOnly()));

            var m = ExpressionSlim.Call(method);

            Assert.AreNotSame(m, m.Update(intExpr1, new ExpressionSlim[] { intExpr2 }.ToReadOnly()));
            Assert.AreNotSame(m, m.Update(@object: null, new ExpressionSlim[] { intExpr2 }.ToReadOnly()));

            var na = ExpressionSlim.NewArrayInit(SlimType);

            Assert.AreNotSame(na, na.Update(new ExpressionSlim[] { intExpr1 }.ToReadOnly()));

            var nb = ExpressionSlim.NewArrayBounds(SlimType, intExpr1);

            Assert.AreNotSame(nb, nb.Update(new ExpressionSlim[] { intExpr2 }.ToReadOnly()));

            var ctor = SlimType.GetConstructor(new TypeSlim[] { SlimType }.ToReadOnly());
            var n    = ExpressionSlim.New(ctor, ExpressionSlim.Parameter(SlimType));

            Assert.AreNotSame(n, n.Update(new ExpressionSlim[] { ExpressionSlim.Default(SlimType) }.ToReadOnly()));

            var t = ExpressionSlim.TypeIs(intExpr1, SlimType);

            Assert.AreNotSame(t, t.Update(intExpr2));

            var u = ExpressionSlim.Not(boolExpr1);

            Assert.AreNotSame(u, u.Update(boolExpr2));
        }
示例#26
0
 public void ExpressionSlim_ToString_Constant()
 {
     AssertToString(ExpressionSlim.Constant(ObjectSlim.Create(value: null, typeof(string).ToTypeSlim(), typeof(string)), typeof(string).ToTypeSlim()), "Constant(null, System.String)");
     AssertToString(Expression.Constant(value: null, typeof(string)).ToExpressionSlim(), "Constant(null, System.String)");
     AssertToString(Expression.Constant("bar", typeof(string)).ToExpressionSlim(), "Constant(bar, System.String)");
 }
示例#27
0
        /// <summary>
        /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression.
        /// </summary>
        /// <param name="breakLabel">The <see cref="BreakLabel" /> property of the result.</param>
        /// <param name="continueLabel">The <see cref="ContinueLabel" /> property of the result.</param>
        /// <param name="body">The <see cref="Body" /> property of the result.</param>
        /// <returns>This expression if no children changed, or an expression with the updated children.</returns>
        public LoopExpressionSlim Update(LabelTargetSlim breakLabel, LabelTargetSlim continueLabel, ExpressionSlim body)
        {
            if (breakLabel == BreakLabel && continueLabel == ContinueLabel && body == Body)
            {
                return(this);
            }

            return(new LoopExpressionSlim(body, breakLabel, continueLabel));
        }
示例#28
0
 internal LoopExpressionSlim(ExpressionSlim body, LabelTargetSlim @break, LabelTargetSlim @continue)
 {
     Body          = body;
     BreakLabel    = @break;
     ContinueLabel = @continue;
 }
示例#29
0
        public void ListArgumentProvider_All()
        {
            var s = typeof(string).ToTypeSlim();
            var i = typeof(int).ToTypeSlim();
            var m = s.GetSimpleMethod("Substring", new ReadOnlyCollection <TypeSlim>(new[] { i, i }), s);

            var a0 = ExpressionSlim.Default(i);
            var a1 = ExpressionSlim.Default(i);
            var d  = ExpressionSlim.Default(i);

            var c = ExpressionSlim.Call(m, a0, a1);

            var argProvider = new ListArgumentProviderSlim(c, a0);

            Assert.ThrowsException <NotSupportedException>(() => argProvider[0] = a0);
            Assert.ThrowsException <NotSupportedException>(() => argProvider.Add(a0));
            Assert.ThrowsException <NotSupportedException>(() => argProvider.Clear());
            Assert.ThrowsException <NotSupportedException>(() => argProvider.Insert(0, a0));
            Assert.ThrowsException <NotSupportedException>(() => argProvider.Remove(a0));
            Assert.ThrowsException <NotSupportedException>(() => argProvider.RemoveAt(0));

            Assert.ThrowsException <ArgumentOutOfRangeException>(() => argProvider[-1]);
            Assert.ThrowsException <ArgumentOutOfRangeException>(() => argProvider[2]);
            Assert.AreSame(a0, argProvider[0]);
            Assert.AreSame(a1, argProvider[1]);

            Assert.AreEqual(2, argProvider.Count);

            Assert.IsTrue(argProvider.IsReadOnly);

            Assert.IsTrue(argProvider.Contains(a0));
            Assert.IsTrue(argProvider.Contains(a1));
            Assert.IsFalse(argProvider.Contains(d));

            Assert.AreEqual(0, argProvider.IndexOf(a0));
            Assert.AreEqual(1, argProvider.IndexOf(a1));
            Assert.IsTrue(argProvider.IndexOf(d) < 0);

            var arr = new ExpressionSlim[5];

            argProvider.CopyTo(arr, 2);
            Assert.IsNull(arr[0]);
            Assert.IsNull(arr[1]);
            Assert.AreSame(a0, arr[2]);
            Assert.AreSame(a1, arr[3]);
            Assert.IsNull(arr[4]);

            var e1 = argProvider.GetEnumerator();

            Assert.IsTrue(e1.MoveNext());
            Assert.AreSame(a0, e1.Current);
            Assert.IsTrue(e1.MoveNext());
            Assert.AreSame(a1, e1.Current);
            Assert.IsFalse(e1.MoveNext());

            var e2 = ((IEnumerable)argProvider).GetEnumerator();

            Assert.IsTrue(e2.MoveNext());
            Assert.AreSame(a0, e2.Current);
            Assert.IsTrue(e2.MoveNext());
            Assert.AreSame(a1, e2.Current);
            Assert.IsFalse(e2.MoveNext());
        }
示例#30
0
 internal LabelExpressionSlim(LabelTargetSlim label, ExpressionSlim defaultValue)
 {
     Target       = label;
     DefaultValue = defaultValue;
 }